{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 分类训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 机器学习的HelloWorld ，一个新的分类算法，都会看看在MNIST的上的执行结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'\\x00\\x00\\x00\\x02'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import struct\n",
    "struct.pack('>i',2) # 高位字节"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./g1.png)\n",
    "![jupyter](./g2.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2051, 60000, 28, 28)\n",
      "47040000\n"
     ]
    }
   ],
   "source": [
    "import struct\n",
    "with open('./MNIST_data/train-images-idx3-ubyte', 'rb') as f:\n",
    "    buffer = f.read(4*4) # 4个int\n",
    "    head = struct.unpack('>iiii',buffer)\n",
    "    print(head)\n",
    "    length = head[1] * head[2]  * head[3]\n",
    "    print(length)\n",
    "    buffer = f.read(length)\n",
    "#   print(buffer)\n",
    "    data = struct.unpack('>{}B'.format(length),buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "47040000"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "imgs = np.reshape(data, (head[1], head[2], head[3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 28, 28)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "imgs.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "for i in range(5):\n",
    "    plt.imshow(imgs[i], cmap = 'gray')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/deprecation.py:85: DeprecationWarning: Function fetch_mldata is deprecated; fetch_mldata was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n",
      "/opt/anaconda3/lib/python3.7/site-packages/sklearn/utils/deprecation.py:85: DeprecationWarning: Function mldata_filename is deprecated; mldata_filename was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_mldata\n",
    "mnist = fetch_mldata('MNIST original', data_home='./')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DESCR': 'mldata.org dataset: mnist-original',\n",
       " 'COL_NAMES': ['label', 'data'],\n",
       " 'target': array([0., 0., 0., ..., 9., 9., 9.]),\n",
       " 'data': array([[0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        ...,\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mnist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* DESCR 数据集描述\n",
    "* data 包含一个数组，每个实例为一行，每个特征为一列\n",
    "* target 包含一个带有标签的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "X, y = mnist['data'], mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000, 784)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000,)"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit = X[40000]\n",
    "some_digit_image = some_digit.reshape(28, 28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD4CAYAAAAq5pAIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAOEElEQVR4nO3db4xU9b3H8c/30tYHthqUVVdRt7cBck0TaDMSE28qN82tiibYxArENFxjsk2UBCKJ13Cj5YFGNJSq0TSBKynX9NIUWgMaY4tIgviAOBpcsEQUs/ypG1j0Qa1PUPneB3u8WWHnd8Y558yZ5ft+JZuZOd+Z+X2Z8NkzO78552fuLgDnvn+quwEA3UHYgSAIOxAEYQeCIOxAEN/o5mDTpk3zgYGBbg4JhDI8PKyTJ0/aRLVCYTezmyQ9KWmKpP9299Wp+w8MDKjZbBYZEkBCo9FoWev4bbyZTZH0jKSbJV0jabGZXdPp8wGoVpG/2edKet/dP3D3U5J+L2lBOW0BKFuRsF8h6ei428eybV9hZoNm1jSz5ujoaIHhABRRJOwTfQhw1ndv3X2duzfcvdHX11dgOABFFAn7MUlXjrs9XdKHxdoBUJUiYX9D0gwz+66ZfUvSIknbymkLQNk6nnpz98/NbKmkP2ts6m2Du79TWmcASlVont3dX5L0Ukm9AKgQX5cFgiDsQBCEHQiCsANBEHYgCMIOBNHV49lx7tm8eXOyvnDhwsrGPn36dGXPfS5izw4EQdiBIAg7EARhB4Ig7EAQhB0Igqk3FDI0NJSsm014VuO2PPTQQx0/Fmdjzw4EQdiBIAg7EARhB4Ig7EAQhB0IgrADQTDPjqRNmzYl62vWrOn4uefOnZusDw4OdvzcOBt7diAIwg4EQdiBIAg7EARhB4Ig7EAQhB0Ignn2c9yhQ4eS9ZUrVybrBw8eTNZPnTqVrJ933nktaw8++GDysf39/ck6vp5CYTezYUmfSPpC0ufu3iijKQDlK2PP/m/ufrKE5wFQIf5mB4IoGnaX9Bcze9PMJvwis5kNmlnTzJqjo6MFhwPQqaJhv97dfyjpZkn3mtmPzryDu69z94a7N/r6+goOB6BThcLu7h9mlyckPS8pfRgTgNp0HHYzO9/MvvPldUk/kbS/rMYAlKvIp/GXSno+Oy/4NyT9r7u/XEpXKE3ePPqWLVuSdXdP1vPOC79q1aqWtfnz5ycfi3J1HHZ3/0DS7BJ7AVAhpt6AIAg7EARhB4Ig7EAQhB0IgkNczwGrV69uWdu8eXOh586bervjjjuS9fvvv7/Q+CgPe3YgCMIOBEHYgSAIOxAEYQeCIOxAEIQdCIJ59kng4YcfTtYfeeSRlrW8Q1DzzJo1K1l/9NFHCz0/uoc9OxAEYQeCIOxAEIQdCIKwA0EQdiAIwg4EwTx7D9i0aVOynppHl/KXTU4ZGBhI1l9+OX128KuvvrrjsfMMDw8n6yMjI8n6xRdf3LI2c+bMTlqa1NizA0EQdiAIwg4EQdiBIAg7EARhB4Ig7EAQzLP3gMcffzxZLzKPPm3atGQ9b0nnKufRDx06lKzfeuutyfq7776brF911VUta3nn07/22muT9ckod89uZhvM7ISZ7R+37SIz225m72WXU6ttE0BR7byN/62km87Y9oCkHe4+Q9KO7DaAHpYbdnffJenjMzYvkLQxu75R0m0l9wWgZJ1+QHepu49IUnZ5Sas7mtmgmTXNrDk6OtrhcACKqvzTeHdf5+4Nd2/09fVVPRyAFjoN+3Ez65ek7PJEeS0BqEKnYd8maUl2fYmkreW0A6AqufPsZrZJ0jxJ08zsmKRfSlot6Q9mdrekI5J+VmWTk93WrenfhW+//XayXuTc788880yyfvvtt3f83O1IHZO+fv365GMPHjxYaOyjR4+2rN13333Jx7722muFxu5FuWF398UtSj8uuRcAFeLrskAQhB0IgrADQRB2IAjCDgTBIa4lePHFF5P1J554Ill390LjX3755S1rM2bMKPTcefKmx2688caWtcOHDxcau8jr9vrrryfrW7ZsSdarnrKsAnt2IAjCDgRB2IEgCDsQBGEHgiDsQBCEHQiCefYSPPfcc8n6rl27kvW8Q1jzTuecOi3y7Nmzk4/NkzePfssttyTrR44caVkrcuiulP9vGxoaKvT85xr27EAQhB0IgrADQRB2IAjCDgRB2IEgCDsQBPPsmY8++ihZ3759e8vazp07y27nKxYuXJisNxqNysZOHY8upefR88ydOzdZzzsPwKJFizoeOyL27EAQhB0IgrADQRB2IAjCDgRB2IEgCDsQBPPsmVdffTVZv/POOysb+4ILLkjWly9fXtnYefLO7V7kmPQVK1Yk67NmzUrWi/Q2c+bM5GOvu+66ZH0yyt2zm9kGMzthZvvHbVtlZn8zs73Zz/xq2wRQVDtv438r6aYJtv/a3edkPy+V2xaAsuWG3d13Sfq4C70AqFCRD+iWmtlQ9jZ/aqs7mdmgmTXNrDk6OlpgOABFdBr230j6nqQ5kkYk/arVHd19nbs33L3R19fX4XAAiuoo7O5+3N2/cPfTktZLSh++BKB2HYXdzPrH3fyppP2t7gugN+TOs5vZJknzJE0zs2OSfilpnpnNkeSShiX9osIez3lbt25N1i+77LIuddJdeefbf+yxxyob+6677krWp0+fXtnYdckNu7svnmDzsxX0AqBCfF0WCIKwA0EQdiAIwg4EQdiBIDjENePuheop8+bNS9ZvuOGGjp+7akX+3XleeOGFQo/P6+3pp59uWbvnnnsKjT0ZsWcHgiDsQBCEHQiCsANBEHYgCMIOBEHYgSCYZ8/s27cvWS9yyuSBgYGOH9uO1HLTeafIzpP37y7yuhR19OjRZP1cPTS4U+zZgSAIOxAEYQeCIOxAEIQdCIKwA0EQdiAI5tkzu3btquy5N27cmKwfOHAgWc+by/70009b1vbvn7yn9F+wYEGy/tlnnyXrU6ZMKbOdSY89OxAEYQeCIOxAEIQdCIKwA0EQdiAIwg4EwTx7ZunSpcn67t27Kxt7z549yXqdx4zXKW8p67zj2V955ZWWtQsvvLCjniaz3D27mV1pZjvN7ICZvWNmy7LtF5nZdjN7L7ucWn27ADrVztv4zyWtcPd/kXSdpHvN7BpJD0ja4e4zJO3IbgPoUblhd/cRd38ru/6JpAOSrpC0QNKX3wPdKOm2qpoEUNzX+oDOzAYk/UDSHkmXuvuINPYLQdIlLR4zaGZNM2uOjo4W6xZAx9oOu5l9W9IfJS1397+3+zh3X+fuDXdv9PX1ddIjgBK0FXYz+6bGgv47d/9Ttvm4mfVn9X5JJ6ppEUAZcqfebGze51lJB9x97bjSNklLJK3OLtPzJD1u9uzZyfqyZcta1p588smy2+kZa9euzb9TwlNPPdWydvjw4ULPvWbNmmQ94vRaSjvz7NdL+rmkfWa2N9u2UmMh/4OZ3S3piKSfVdMigDLkht3dd0tq9a2OH5fbDoCq8HVZIAjCDgRB2IEgCDsQBGEHgjB379pgjUbDm81m18YDomk0Gmo2mxPOnrFnB4Ig7EAQhB0IgrADQRB2IAjCDgRB2IEgCDsQBGEHgiDsQBCEHQiCsANBEHYgCMIOBEHYgSAIOxAEYQeCIOxAEIQdCIKwA0EQdiAIwg4EQdiBIHLDbmZXmtlOMztgZu+Y2bJs+yoz+5uZ7c1+5lffLoBOtbM+++eSVrj7W2b2HUlvmtn2rPZrd19TXXsAytLO+uwjkkay65+Y2QFJV1TdGIByfa2/2c1sQNIPJO3JNi01syEz22BmU1s8ZtDMmmbWHB0dLdQsgM61HXYz+7akP0pa7u5/l/QbSd+TNEdje/5fTfQ4d1/n7g13b/T19ZXQMoBOtBV2M/umxoL+O3f/kyS5+3F3/8LdT0taL2ludW0CKKqdT+NN0rOSDrj72nHb+8fd7aeS9pffHoCytPNp/PWSfi5pn5ntzbatlLTYzOZIcknDkn5RSYcAStHOp/G7JU203vNL5bcDoCp8gw4IgrADQRB2IAjCDgRB2IEgCDsQBGEHgiDsQBCEHQiCsANBEHYgCMIOBEHYgSAIOxCEuXv3BjMblXR43KZpkk52rYGvp1d769W+JHrrVJm9Xe3uE57/rathP2tws6a7N2prIKFXe+vVviR661S3euNtPBAEYQeCqDvs62oeP6VXe+vVviR661RXeqv1b3YA3VP3nh1AlxB2IIhawm5mN5nZu2b2vpk9UEcPrZjZsJnty5ahbtbcywYzO2Fm+8dtu8jMtpvZe9nlhGvs1dRbTyzjnVhmvNbXru7lz7v+N7uZTZF0UNK/Szom6Q1Ji939r11tpAUzG5bUcPfav4BhZj+S9A9J/+Pu38+2PS7pY3dfnf2inOru/9kjva2S9I+6l/HOVivqH7/MuKTbJP2HanztEn3doS68bnXs2edKet/dP3D3U5J+L2lBDX30PHffJenjMzYvkLQxu75RY/9Zuq5Fbz3B3Ufc/a3s+ieSvlxmvNbXLtFXV9QR9iskHR13+5h6a713l/QXM3vTzAbrbmYCl7r7iDT2n0fSJTX3c6bcZby76Yxlxnvmtetk+fOi6gj7REtJ9dL83/Xu/kNJN0u6N3u7iva0tYx3t0ywzHhP6HT586LqCPsxSVeOuz1d0oc19DEhd/8wuzwh6Xn13lLUx79cQTe7PFFzP/+vl5bxnmiZcfXAa1fn8ud1hP0NSTPM7Ltm9i1JiyRtq6GPs5jZ+dkHJzKz8yX9RL23FPU2SUuy60skba2xl6/olWW8Wy0zrppfu9qXP3f3rv9Imq+xT+QPSfqvOnpo0dc/S3o7+3mn7t4kbdLY27rPNPaO6G5JF0vaIem97PKiHurtOUn7JA1pLFj9NfX2rxr703BI0t7sZ37dr12ir668bnxdFgiCb9ABQRB2IAjCDgRB2IEgCDsQBGEHgiDsQBD/B+1rQqO0BZUjAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(some_digit_image, cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.0"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[40000]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建立测试集和训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([36599, 19787, 58323, ...,  4720, 46388, 52469])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据集合交叉洗牌，交叉验证时，每个子集合数据分布均匀，有些机器学习算法对训练实例的顺序敏感\n",
    "import numpy as np\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "shuffle_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 784)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练一个二元分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, ..., False, False, False])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 识别数字5 ，二元分类5或者非5\n",
    "# 创建目标向量\n",
    "y_train_5 = (y_train == 5.0)\n",
    "y_train_5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False,  True, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       ...,\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False,  True, ..., False, False, False]])"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_5.reshape(15, -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_5 = (y_test == 5) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import SGDClassifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SGDClassifier(alpha=0.0001, average=False, class_weight=None,\n",
       "              early_stopping=False, epsilon=0.1, eta0=0.0, fit_intercept=True,\n",
       "              l1_ratio=0.15, learning_rate='optimal', loss='hinge',\n",
       "              max_iter=1000, n_iter_no_change=5, n_jobs=None, penalty='l2',\n",
       "              power_t=0.5, random_state=None, shuffle=True, tol=0.001,\n",
       "              validation_fraction=0.1, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf = SGDClassifier()\n",
    "clf.fit(X_train, y_train_5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# SGD 梯度下降 分类器\n",
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(random_state = 42)\n",
    "sgd_clf.fit(X_train, y_train_5)\n",
    "\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 性能考核"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用交叉验证测量精度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.959  , 0.95955, 0.96515])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 评估分类器比评估回归器要困难得多\n",
    "\n",
    "# 3个折叠，正确率达到 95% 以上\n",
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\") # cv表示在cross validation时，将训练集切分的份数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 把每张图都分类成 非5\n",
    "from sklearn.base import BaseEstimator\n",
    "class Never5Classifier(BaseEstimator):\n",
    "    def fit(self, X, y=None):\n",
    "        pass\n",
    "    def predict(self, X):\n",
    "        return np.zeros((len(X), 1), dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False],\n",
       "       [False],\n",
       "       [False],\n",
       "       ...,\n",
       "       [False],\n",
       "       [False],\n",
       "       [False]])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros((len(X), 1), dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.91335, 0.90535, 0.91025])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "never_5_clf = Never5Classifier()\n",
    "cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 准确率超过90% ，因为5的图像大约只有10%，你猜一张图不是5， 90%的时间你都是正确的\n",
    "* 这说明准确率无法成为分类器的首要性能指标，特别是当你处理偏科数据集， 某些类比其他类更为频繁"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    }
   ],
   "source": [
    "# 评估分类器性能的更好方法是混淆矩阵\n",
    "# A类别实例被分为B类别次数\n",
    "# 想要知道分类器将数字3和数字5混淆多少次，通过混淆矩阵的5行3列\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 与 cross_val_score 相比\n",
    "* 同样执行交叉验证\n",
    "* 返回的不是评估分数，是每个折叠的预测\n",
    "* 每一个实例在模型预测时使用的数据，在训练期间从未见过"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[54200,   379],\n",
       "       [ 1947,  3474]])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "confusion_matrix(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 行表示实际类别，列表示预测类别\n",
    "# 第一行 第一列 53272 被正确的分为 非5 ，真负类\n",
    "# 第一行 第二列 1307 被错误的分类成 5 ，假正类\n",
    "# 第二行 第一列 1077 张被错误的分为 非5， 假负类\n",
    "# 第二行 第二列 4344 张被正确的分在了5 ，真正类\n",
    "# 这种衡量方式太复杂，我们可以用更简单的指标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[54579,     0],\n",
       "       [    0,  5421]])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_perfect_predictions = y_train_5\n",
    "confusion_matrix(y_train_5, y_train_perfect_predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 正类预测的准确率 被称为分类器的精度\n",
    "\n",
    "\n",
    "$\n",
    "\\text{精度} = \\cfrac{TP}{TP + FP}\n",
    "$\n",
    "\n",
    "TP是真正类的数量，FP是假正类的数量\n",
    "\n",
    "\n",
    "\n",
    "$\n",
    "\\text{召回率TPR} = \\cfrac{TP}{TP + FN}\n",
    "$\n",
    "* 检测正类实例的比例\n",
    "FN是假负类的数量\n",
    "![jupyter](./zhaohui.jpg)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度和召回率\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9016350895406177"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score\n",
    "\n",
    "precision_score(y_train_5, y_train_pred) # 4327 / 4327 + 1276"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6408411732152739"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred)    #  4327 / 4327 + 1094"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 说明 检测一张图的时候，只有90%的概率是准确的，而且只有64%的数字5 被它检测出来\n",
    "# 精度和召回率合成单一指标，成为 F1 分数，谐波平均值\n",
    "# 平均值平等对待所有的值，谐波平均值会给予较低值更高的权重，只有召回率和精度都很高时，才能获得较高的F1分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\n",
    "F_1 = \\cfrac{2}{\\cfrac{1}{\\text{precision}} + \\cfrac{1}{\\text{recall}}} = 2 \\times \\cfrac{\\text{precision}\\, \\times \\, \\text{recall}}{\\text{precision}\\, + \\, \\text{recall}} = \\cfrac{TP}{TP + \\cfrac{FN + FP}{2}}\n",
    "$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7491912874703472"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "f1_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "# F1分数对那些具有相近精度和召回率 分类器更有利，这不一定符合你的期望\n",
    "# 有时候你更关心精度，有时你能关心召回率\n",
    "# 训练一个分类器检测儿童可以放心观看的视频，你可能要求拦截了很多好的视频，低召回率，保留下来的都是安全的视频，高精度\n",
    "# 不能同时增加精度并减少召回率，反之亦然"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度/召回率权衡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./quanheng.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* SGDClassifier对每个实例基于决策函数计算一个分值，大于阀值为正类，否则为负类\n",
    "* 中间阀值右侧找到4个真正类 真5 ， 一个假正类 6， 精度为 4/5 80%\n",
    "* 在所有的6个 真正的5 中，分类器找到了4个，召回率为 4/6 67%\n",
    "* 提高阀值，向右移动，精度提高，召回降低\n",
    "* 反之阀值降低，召回提高，精度降低\n",
    "* SKlearn不可以直接设置阀值，可以访问决策分数，\n",
    "* SGDClassifier 默认阀值为0 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何设置阀值\n",
    "\n",
    "# 用predict_proba得到每个实例属于正类的概率，然后对概率切一下。以LogisticRegression为例\n",
    "# clf = LogisticRegression()\n",
    "# clf.fit(X_train, y_train)\n",
    "# pred_proba = clf.predict_proba(X_test)[:, 1]\n",
    "# threshold = 0.75  # 阀值设置为0.75\n",
    "# pred_label = pred_proba > threshold\n",
    "\n",
    "# pred_proba是每个实例为真的概率\n",
    "# 假设阈值是0.75\n",
    "# pred_label里True就是概率大于0.75的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([42217.83953346])"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回决策值decision_function\n",
    "y_scores = sgd_clf.decision_function([some_digit])\n",
    "y_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = 0\n",
    "y_some_digit_pred = (y_scores > threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 提高阀值可以降低召回率，提高阀值到200000，就错了这个图\n",
    "threshold = 200000\n",
    "y_some_digit_pred = (y_scores > threshold)\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    }
   ],
   "source": [
    "# 如何决定使用什么阀值\n",
    "# 返回决策值，而不是预测结果\n",
    "y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n",
    "                             method=\"decision_function\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000,)"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有了y_scores，可以计算所有可能的阀值的精度和召回率\n",
    "y_scores.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import precision_recall_curve\n",
    "\n",
    "precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib 绘制精度和召回相对于阀值的函数图\n",
    "def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n",
    "    plt.plot(thresholds, precisions[:-1], \"b--\", label=\"Precision\", linewidth=2)\n",
    "    plt.plot(thresholds, recalls[:-1], \"g-\", label=\"Recall\", linewidth=2)\n",
    "    plt.xlabel(\"Threshold\", fontsize=16)\n",
    "    plt.legend(loc=\"upper left\", fontsize=16)\n",
    "    plt.ylim([0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 4))\n",
    "plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n",
    "plt.xlim([-700000, 700000])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAf0AAAF5CAYAAACV7fNGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XmcVmX9//H3hxlgEFDZBERcwBV3GRdI/QK5lIpbuIumuZVRVn77ZlqWmmmLpvZ1If2qlVlYrj8tMYncMBpUEhVzRRFBEASRRZj5/P647unMDLPcM3Pf57qX1/PxmMe57vs+c+6Px3nwPuc617mOubsAAEDp6xK7AAAAkA5CHwCAMkHoAwBQJgh9AADKBKEPAECZIPQBACgThD4AAGUi9dA3s4Fm9mQrn3c1s4fM7GkzOzPN2gAAKGWphr6Z9ZF0p6Seraw2SdIsd/+MpAlm1juV4gAAKHFpn+nXSjpB0opW1hkjaUqm/YSk6jzXBABAWahM88vcfYUkmVlrq/WU9F6mvVTSwKYrmNk5ks4Jr/qNlLbWzjtLVVW5rBYAgMI0a9asJe4+oL2/l2roZ2mlpB6SlkvqlXndiLtPljRZkqqqqn3t2hrde6+0/fap1gkAQBRmNq8jv1eIo/dnSdo/095d0tvZ/FK2zw1atkx64AHp/fcbv//pp9I//iH98Y/SqlXZlgoAQPGIeqZvZuMkjXD3XzZ4+05Jj5jZAZJGSPpHZ7/HXfr736Vf/CIEviQdf7x06aXSffdJjz4q/fOf0po14bMrrpAuvjj53XnzpBdekF56SZozJyxffVX63vek3r2lXXeVxowJBxJvvZX8vP12WM6dK333u1KXLtIxx0hm0pIl0k47SZWVUm2ttHSp1L9/+Kyz6rf34YfSsGFSt27hoGbt2lAvAKA8WSE+WtfMNlc423/U3Ze3tm599/4rr0g77rjh53PnSuedF0K/Pa65Rnr6aemZZzbsFWi+juSgoT223FKaP1+qqwuv77lH+uADadEiady4cNCxYEGooeHytdekgQOlffaRFi9u/LN0aeOej169pJUNLpJUVEhPPinttltYd8iQcEACACgOZjbL3ds90L0gQ789Wgv9O++Uzj03nOH26SN9/esh6I49Nnzet6905JHh58ADw5l5dTO7sF+/8P4uu0g77ywtXy5df7201VbS9OnJegMGhDPrrbeWttkmLN94Q/rrX6WPP5Zefz0/+6A5PXpIq1dnv/7xx0sffRQONmbPlmbMkDbbTBo8OGwLAFA4CP0mof/LX0qTJoX2F78oXXuttOmmoev7llvC2e3hh4fu9Xru0tFHS7NmSQcdFA4ERo+Wdtih5W73RYtCF/4OO4QDi9Z8/HE4y+7RQ3r22dDlPnSotPnmofv/vvvCf8PHH4dehmHDwmeDBzde9usnPfxwCOUBAxr/9O8fPq+sDNtZvDi87t1bevnl8Hvf+U779vG++4YDnT/8IRw0NVVXF8ZKLF4cLls0XC5eLL34YuiRqK0Nlxzmzg0HRRtvHC6bHHKI9M470s9/HvbN0qVhe0uXhv2z1VbtqxcASl3Zh/7LL4dr5FK4Rn/YYSGMrr8+CX8E69eH3o+NNgoHONOmSYMGhQOGP/xB+vWvw2ctDWjs3TscUGy3Xegd+PDD5PJEvv3pT+E7jzoqHMRVVKTzvQBQSMo29Hv0qPY1a5LQ//jjcLa8YEEYqPeDH8SusHgtXCg98kgYvHjtta2v26dPOGio722oXy5fHnpDhg8PPQ7uocdhu+3CpY/KytD7sGhR2E5lZbjs0rdv6BFory5dpG23lQ49VBo1StpiizBGYtSo0EsCAKWg7EP/pZekESOk739fuvzy0J38zDOcCeaKe7hjQZK6dw93NNSHe9++Uteundv+unVhIGSvXsmllNpa6d13w3sDBkj77Rcui3RGfS/FyJHhQOSb3ww9FbvuGu5yqKtLJnnq1i30eKxbF/776utyDwMjly4NtfXr17maAKC9CP2XwrXfLbcM/xg/8YR0wAGxq0O+1NWF/88LF4Zgfu896bnnpKlTpZqacHa/xRYhwHM5gHKzzcL3rl/f+P3NNw+9S4cfHgZCvv++dPXVobdi/Phw+WTkyHDgwJ0SADqr7EN/zhzp+eeliRPDWf6zz+bmnneUhiVLpJkzQzDPnh0Geg4cGHoXlrd6U2jzevaUPvmk4/Wcckq4HPWFL4TLEStXhoOXTz4JByq1tWFZVxd6HACgIUJ/ThiV/v/+X/gH/fzzY1eGYuQeDhZra0N79epwR8GcOSF8+/YN4xe6dw/rv/NOOJB49dWw7kYbSZdcEsYQTJkSzupzNchx223DXSLbbht6sY48svFllfraAZS+sg/9554Lt9etWRO6VgcNil0ZkHAPYwMeeEA644xw8PDuu7nbfsO7LXbbTfrXv8KYiy98IcwWudlm4TbV4cMb36YKoDiVfejfckuYiGfEiDBNLlAM3MP4gK5dQ+9CRUXoGairC2fty5ZJd90V/qb/8pdw4LBwYW6++5xzwrbGjZNOPZUBiUAxKfvQP+WU8I/jeedJN90Uuyog/1auDHceuIfAfv/9cDukWZjc6ac/bf82v/zlMK5gyRLpqafCuIezzgqXM3bZJVxeGDAgubwBII6yD/2ddw5nQ7ffHmbgA9BYXV2YiOnJJ8MTJadNCz0HnXX44WFujHffDTMt7rRTmE1y223DOAh6EIDcK/vQrzdzprT33hELAoqMexj8+tpr4bbXfv2kFSvC7IdVVdKbb4bnUjS9TbE9Dj9cGjs2TD09enS4w4ZnOgAdR+hnfPxxmDAFQH6sXx+mQr7nntBjsO22YWzAnDnhbH/FinB5IBsjRoRHWQ8cGC4rDBwobb99MkESgOaVbehvtFG1r14dQn/o0HALFYDC8Mwz0pVXhomSHnss9Bq01zbbSHvtFQbqDh4cDgj69w/PXgDKFaGvcO/yE09ELghAm9asCfMMTJsWDta7dOnYAcFBB0nHHRcel92/f+7rBApVR0O/pCYE3WKL2BUAyEZVVZgyef368GjqN94IYwvq6sLgwlWrwnv33x/uGujTJwwObOqvfw09AAMGhLsWzMKBwMMPp//fBBSDkgr9oUNjVwCgM8zC5EE9eoSQP+oo6cUXw/MO6g8MamvDHQjjxzc/GPDxx6Ujjgjb+uxnpXvvDb8HoMRCnzN9oPR16SLtv7/04IOhR8A9DCycOlX69rcbrzttWpiVsEuXcBCw9dbhIAAoVyUV+ky9C5SnTTaRDj44PNnQPTx8a9CgcDdAQ/PmhYMAs/A0RqDclFToMwkIAEnaY48wQ+HChWGcQE1NmFmwob33DpcE33svTo1ADIQ+gJJmJo0cKf3qV6EX4M47k8/mzw+XBRctilcfkCZCH0BZOe20cIfARRcl7w0aFA4Ohgyh2x+ljdAHUHYqK8OkQVde2fj9BQtCt79ZGA/wt7/FqQ/Il6KfnKeqqtrXrg2H5kX+nwIgkr/9TZo0qeXHcp9zTugF2G8/6ZBD0q0NaE7ZzsjXrVu1r1tH6APIjQULpC99SfrLX5r/fIcdwiO8jzgiPHcAiKFsQ7+ystprawl9ALlVVyd9/evSc8+FiYJ++9vm16uokJYvl3r2TLc+lLeynYa3tjZ2BQBKUZcu0g03SE8/Lf3mN2HK4Asu2HA+kNra8GTP+mmA77ijc48hBvKp6M/0zapdqlG3btLatbGrAVAO3MNjvEeOlF5/vfl1+vULcwV07ZpubSgPZXumX69Xr9gVACgXZtLGG0uvvRZu/3vppQ17AD78UOrWLax79NHSJ5/EqRVoqGRCn+tpAGKorJRGjAhn9e7SihXSqFGN13nggXBicu654UABiKVkQp8zfQCFoHdv6ZlnpGXLpMmTG88fMnmytP324ez/ySfj1YjyVTKhz5k+gEKy6abS2WdLS5aE+f3NGn9+4IHhMcBAmkom9Jt7rjYAFILNNw+3ALpLt9+evH/QQcmo//3357Zj5F/JhH737rErAIC2ffGL0t13b/j+00+H2wTNpDVrUi8LZYLQB4CUnXhictvfK6+EcQAN9egh7bhj+BzIJUIfACLp1SuE+4oVYUKf4cOTz159NdwW2K8f3f7IHUIfAApARUWY6GfJksbvL10auv3PPjvcFgh0RsmEfrdusSsAgM6rP7N3D4/3rXfrrWFAoJm0ySZc90fHlEzoc6YPoNQsXBgm9tlhh8bvr1gRrvv/6U9hRkAgW4Q+ABSwI4+U5s4NZ/7Ll0tDhiSfTZgQejnvuCNaeSgyJRP6dO8DKHUbbyzNnx/O8DffPHn/jDOkwYPj1YXiUTKhz5k+gHJx7LFhlr8XX0zeW7gwXO9/9tl4daHwlUzoc6YPoNzssou0enXj90aNCoP+gOaUTOg3fKgFAJSLqqpwj/+eeybvnX12OOtfsCBeXShMRR/622wTnlV91lmxKwGAOCoqpOee27Brf8gQ6c0349SEwlT0od+3r3TffeFoFwDK2b77hlH+V1yRvDd8+IZP+EP5KvrQBwA0dvHF0k03NX6P7n5IhD4AlKTzzttwzv4hQ6THHotTDwoDoQ8AJay2Vvr2t5PXhxwi7bNPvHoQF6EPACWsSxfp6qvDQL96//xn6O6fPj1aWYiE0AeAMrDnnhvO0z92rHTjjXHqQRyEPgCUicrKcJ3/hhuS984/X/rkk3g1IV2EPgCUma9+NczhX69XL+ndd+PVg/QQ+gBQhoYMkX73u+T1lltKixbFqwfpIPQBoEyddJJ0113J60GDpA8+iFcP8o/QB4AydvLJjQfzDRwYHtX7yivxakL+pB76Znabmc0ws0ta+LyPmT1iZjVmdkva9QFAufnyl6Wbb05e33GHNGKENHNmtJKQJ6mGvpkdK6nC3UdJGmZm2zWz2kRJd7l7taTeZladZo0AUI7OPVd69NFwrb/evvtKEyfGqwm5l/aZ/hhJUzLtqZL2b2adDyXtYmabShoqiTGlAJCCQw4Jo/pnzEje++1vpWXL4tWE3Eo79HtKei/TXippYDPrPCVpK0lfk/RKZr1GzOycTPd/zeLFi/NVKwCUpf32k1avTl737St99FG8epA7aYf+Skk9Mu1eLXz/pZLOc/fLJM2VdEbTFdx9srtXu3v1gAED8lYsAJSrqirprLOS1336SKNHb/gQHxSXtEN/lpIu/d0lvd3MOn0k7WpmFZL2lcSfGABE8KtfSf/zP8nrGTPCXP50sBavtEP/fkkTzewaScdLesnMrmiyzo8lTZa0XFJfSXenWyIAoN5VV0lvv914gN9mm0nPPhutJHSCecp9NWbWR9LBkp5w94Wd3V51dbXX1NR0vjAAQKtuv10688zkNV398ZjZrMxdbu2S+n367r7M3afkIvABAOk54wzp+uuT1089Fa8WdAwz8gEAsnb++Un7gAOkHXaIVwvaj9AHAGStS5fGM/X9+9/SsGHx6kH7EPoAgHbZe2/p00+T12+9JT34YLx6kD1CHwDQbl27Ng7+o46Szj47Xj3IDqEPAOiQrl2lF15IXt96q7TddtKqVfFqQusIfQBAh+2+u1Rbm7x+/XWpZ8949aB1hD4AoFO6dJHq6qTx45P33norXj1oGaEPAOg0s8aD+YYNky67LF49aB6hDwDImZtuStqXXiotWRKvFmyI0AcA5Mx554W5+uvxINTCQugDAHJqq60aP53vmWfi1YLGCH0AQM5ddVXSPvhgHs5TKAh9AEBefPObYblqlTRpUtxaEBD6AIC8+NGPpKFDQ/t//1d6/vm49YDQBwDkSVVV4xn79tpL+s1v4tUDQh8AkEd9+0qzZiWvTzut8Zz9SBehDwDIq732kmbPTl537y599FG8esoZoQ8AyLvddpMmTEhe33VXvFrKGaEPAEjFPfdI48aF9le/GreWckXoAwBS89//nbR5BG/6CH0AQGo+97mkfcwx8eooV4Q+ACBVo0eH5dSp0h57xK2l3BD6AIBUPf540p49O5nAB/lH6AMAUlVVFebi/8pXwuv586WnnopbU7kg9AEAUfzyl0n7rLPi1VFOCH0AQBRm0u23h/arr0rz5sWtpxwQ+gCAaE49NWlvvTWP4M03Qh8AEE1lpfTTnyav66/zIz8IfQBAVBdemLRvvllasiReLaWO0AcARLd2bdI+6KB4dZQ6Qh8AEF23btJ++4X27Nlc288XQh8AUBDuvTdpjx8fr45SRugDAArC4MHSNtuE9sMPc7afD4Q+AKBgPP100j7jjHh1lCpCHwBQMAYPDrfxSdKKFXFrKUWEPgCgoDz0UFjed5+0fn3cWkoNoQ8AKCjV1Um7a9d4dZQiQh8AUFD695cuuCB5ffLJ8WopNYQ+AKDgXHuttNVWoX333dKqVXHrKRWEPgCgIL3xRtLu2TNeHaWE0AcAFKSKCunoo5PX3LffeYQ+AKBg/fGPSfvww+PVUSoIfQBAwaqokLbYIrT//Oe4tZQCQh8AUNDq79uXpOXL49VRCgh9AEBB22OPpL3ppvHqKAWEPgCg4PXqlbQ/+CBeHcWO0AcAFLyGQb/bbvHqKHaEPgCg4PXoIZ1+emgvWhS3lmJG6AMAisJVVyXtdevi1VHMCH0AQFEYNChpd+sWr45iRugDAIrGSSfFrqC4EfoAgKJx881J+6234tVRrAh9AEDR2HjjpH3ssfHqKFaEPgCgqIweHZYvvBC3jmJE6AMAisrvfpe058+PV0cxIvQBAEVlq62S9tNPx6ujGKUe+mZ2m5nNMLNL2ljvRjMbn1ZdAIDiseOOYXniiXHrKDaphr6ZHSupwt1HSRpmZtu1sN4Bkga5+0PNfQ4AKG+XX5609903Xh3FJu0z/TGSpmTaUyXt33QFM+sq6VeS3jazo9IrDQBQLCZMkLbZJrRnzpQOPTRuPcUi7dDvKem9THuppIHNrHOapJcl/UTSPmY2qekKZnaOmdWYWc3ixYvzViwAoHC9+abUr19oT50qrVkTt55ikHbor5TUI9Pu1cL37ylpsrsvlPRbSWObruDuk9292t2rBwwYkLdiAQCF7d//Ttp77hmvjmKRdujPUtKlv7ukt5tZ53VJwzLtaknz8l8WAKAY9e0rjRwZ2nPnxq2lGKQd+vdLmmhm10g6XtJLZnZFk3VukzTWzJ6Q9BVJP0u5RgBAEXnggaRd//hdNM/cPd0vNOsj6WBJT2S68Dulurraa2pqOl8YAKBobbSRtHp1aKcca1GY2Sx3r27v76V+n767L3P3KbkIfAAAJOkf/0ja9eGPDTEjHwCg6O26a9IeMyZaGQWP0AcAlIQvfCEsZ86UliyJW0uhIvQBACXhjjuS9hVNh4hDEqEPACgRvXolZ/vXXVceA/rai9AHAJSMq69O2g3P/BEQ+gCAkjF8uDR4cGifeWbcWgoRoQ8AKCmTJyfteczp2gihDwAoKUcckbTPPjteHYWI0AcAlJz64H/sMWnlyri1FBJCHwBQcn7zm6Tdu3e8OgoNoQ8AKDmbbipddFHymtv3AkIfAFCSfvjDpD1zZrw6CgmhDwAoSV27St27h/Yjj8StpVDkPPTNrEeutwkAQEcceGBYXndd3DoKRZuhb2bdzOyATLvCzMa38SuXm9llOakOAIBOOOqosFy+XFq7Nm4thSCbM/2+kv6aaVdK+n0b6w+WtGlnigIAIBfOPTdpV1VJq1bFq6UQZBP6azM/cve1ktY3/NDM7jKzTRq8NVjSv3JWIQAAHVRZKX31q8nr//qveLUUgmxCv05SrZn9ysw+ltTLzJaZ2cdmdrCkkyTNMbO9M+vvLmlGnuoFAKBdbrhB2muv0J47N24tsbVnIN91ko6S9ImkoyW9kPn95ZK+J+kvZvbfkla7+0u5LhQAgI669dawXLlSWrAgbi0xVWaxzn9JcnefI0lmtt7d/25mSzKfu7vfkXl9v6Rr8lQrAAAdsvvuSXviROnxx+PVElOrZ/pmdq9CkGdj38yye6cqAgAgx7p0kU44IbSnTYtbS0xtde//UtIYSTKzUWZ2hqRuZnaapKGZdSrN7FZJx0n6rKQJZmZ5qhcAgA750Y+S9gcfxKsjplZD392nSZotyRTC/wKFM/lvSdpI0hpJvTKf7+Puf5f0nqQD81cyAADtN3x40t5775bXK2XZDuRzd/+xpD0lrXL33d19hMIo/VXu/iV3X5FZd7qkUbkvFQCAzhmfmV7unXfK85G77Z2Gt0pSw2l2TdIfmqwzR9LIzhQFAEA+TJmStEePjldHLNmM3pek7mZWP73BBWZ2lqRVkt6X9BMz6+Xu9cdMb0i6J8d1AgDQaVVV0pFHSg8+KL34Yuxq0pdN6NdKmivpFEn1TySulNQz8zNIUlcz+7ekqZL+z92nNLchAABiu+GGEPqStG5deBpfuWgz9DNn8K1215vZlpLGSTpR0nNmdqC7P52bEgEAyJ0hQ5L2734nnX56vFrS1u5H65rZADPr3/A9d3/H3e9w989J2p3ABwAUqooKadCg0L7++ri1pC2bR+v2MLNvWVAl6WxJp7W0fv3MfQAAFKrDDgvL556TVqxofd1Sku2Z/jck7SLpRoV78z81s1lmNt/M3mzy86qZ/SBfBQMA0FkNJ+p5+OF4daStzdB399WS1imE/RqFR+uuk9RHYXBfD0lnNFjOkXShmVXkqWYAADpl0CDpmGNC++6749aSplYH8pnZ5xWCvrukakkDFUL/JUnKPHhndWa5JrNcJ+l/FR7JCwBAQRqamUz+oYekurowP3+pa+s/8TeSfi1pgKSfSDpI0smt/YK7P+Pu09zdW1sPAICYvve9pD1/frw60tTW3Pv93X2opPkKc+//WtLlLa2e29IAAMif/v2lnXYK7aOPjltLWtq8Tz9zbb5S4QChm8LUu13CR/Z9SX2aLCVJ7n5ZfkoGACA3Ro2SXnlFev752JWkI5srGFWZn08kzcy0uynMuT9Q4RJAH4VegP6Z97bMR7EAAOTSNdck7Vmz4tWRlmxm5PvEzL4i6VN3v83MjpP0prvPMrMvSRru7t/Ne6UAAOTYJptIG20krVoVuvjffTd2RfmV7VjFkyS9bmYnSvq9pJfN7A5J35H0eJ5qAwAg737847Ash8F8rYa+mZ1gZkdJulPS9ZIyQx50qKSPFAb19TSzIxv8HGNmJ3KfPgCgGJx6atK+vKWh6iXCWruzzsxekbRWYWS+Kwzi213JSP03JK3MvF+vUuG+/r0aPG43b6qrq72mpibfXwMAKGHWIMXq6hq/LkRmNsvdq9v7e23dsreTu+8h6UBJMyT9j0LgT5D0iKRNJd0tqdrd98z87Oru26cR+AAA5MLMmUn7iCPi1ZFv2V7Tn6IwKv9lhbP6R919vKTDJJ0g6WmzQj8uAgCgeXvvnbQfeSReHfnW5uj9jC+6+yJJMrNt3H2VJLl7jZntJ2kfZuADABSzGTPCffuS5F74XfwdkdWZfn3gZ9rzmny23t2fyXVhAACkqbrBFfJx4+LVkU9l8HgBAADaVtmg73v69Ghl5BWhDwBAxhtvJO0nnohXR74Q+gAAZAwbljxy97rr4taSD4Q+AAANHHZYWL74Ytw68oHQBwCggfoR/K+9FreOfCD0AQBooOHkPJ9+Gq+OfCD0AQBooF+/pL1gQbw68oHQBwCgBaXWxU/oAwDQxC67hOUhh8StI9cIfQAAmjjllKRdSpPME/oAADTx7W8n7W98I14duZZ66JvZbWY2w8wuaWO9gWb2fFp1AQBQr0uDdCylSXpSDX0zO1ZShbuPkjTMzLZrZfWfSeqRTmUAADT2yitJ++OP49WRS2mf6Y+RNCXTnipp/+ZWMrNxkj6RtDCdsgAAaGzHHZN2/dS8xS7t0O8p6b1Me6mkgU1XMLNukr4n6TstbcTMzjGzGjOrWbx4cV4KBQDgZz8Ly113jVtHrqQd+iuVdNn3auH7vyPpRnf/qKWNuPtkd6929+oBAwbkoUwAAKQxY8LyqaekurqopeRE2qE/S0mX/u6S3m5mnYMknW9m0yXtYWa3plMaAACN7bBD0r7qqnh15Ip5ijcgmtnGkp6U9Likz0s6UdJx7t7sSH4zm+7uY1rbZnV1tdfU1OS6VAAAJElbby3NmxfahXLPvpnNcvfq9v5eqmf67r5CYTDfs5LGuvvslgI/s/6YlEoDAKBZJ50Uu4LcSf0+fXdf5u5T3J2R+QCAgtdwop6//S1eHbnAjHwAALSiT5+kPW5cvDpygdAHAKANV16ZtJcujVdHZxH6AAC04ZvfTNpXXBGvjs4i9AEAaEP37lJ1Zqz8HXdELaVTCH0AALLwxS+G5bJlUm1t1FI6jNAHACAL9aEvSVOmtLhaQSP0AQDIQs+eUlVVaF92WdxaOorQBwAgS/UT9cydG7eOjiL0AQDI0g9+kLSffDJaGR1G6AMAkKUtt0zahx4ar46OIvQBAGiHm28Oy9WrpYVFNqE8oQ8AQDucc07SHjs2Xh0dQegDANAOZtIFF8SuomMIfQAA2umUU8Ky2EbxE/oAALTTjjsm7Xnz4tXRXoQ+AADt1KtX0t5++3h1tBehDwBAB5xwQlh++qnkHreWbBH6AAB0wF13Je1rr41XR3sQ+gAAdEBFRdL+1rfC0/cKHaEPAEAHzZmTtC++OF4d2SL0AQDooJ13lg47LLRvuiluLdkg9AEA6ISGZ/jvvhuvjmwQ+gAAdMLo0Un7c5+LV0c2CH0AADrpjDPC8uWX49bRFkIfAIBO+slPkvbOO8eroy2EPgAAndS/vzRxYmi//LJUVxe3npYQ+gAA5MBttyXtvfaKV0drCH0AAHKga1fp+ONDe+HCuLW0hNAHACBH6qfjXbSoMLv4CX0AAHJk8OCkffvt8epoCaEPAECOmCXB//rrcWtpDqEPAEAOTZoUllddJa1dG7eWpgh9AABy6IgjkvYVV8SrozmEPgAAObTrrtLw4aH9xz/GraUpQh8AgBy7++6wnDtXco9bS0OEPgAAOVZdnbQLaT5+Qh8AgBwzk7beOrQnTIhaSiOEPgAAeXD66WE5d670wQdxa6lH6AMAkAcXXZS0R4yIV0dDhD4AAHnQvbt09dWh/eGH0vz5ceuRCH0AAPLmwgulioq9/vUMAAAKxklEQVTQHjo0bi0SoQ8AQN506SI9+GDyetWqeLVIhD4AAHl12GFJ++CD49UhEfoAAOTdZz4Tls88I73wQrw6CH0AAPLssceS9nHHxauD0AcAIM969JAuvTS0Yz5yl9AHACAF9Y/claTvfjdODYQ+AAAp6NdPGjYstKdMiVMDoQ8AQEruvz8s33hDWr8+/e8n9AEASMkuuyTtadPS/35CHwCAlJglj9099dT0v5/QBwAgRZ/9bFguXpz+dxP6AACkqP7WPUl65510v5vQBwAgRT16SF27hvbChel+N6EPAEDKRo4My8mT0/1eQh8AgJT17RuW996b7vcS+gAApOyUU8KyR490vzf10Dez28xshpld0sLnm5jZn81sqpndZ2bd0q4RAIB82mmnsFywIN3vTTX0zexYSRXuPkrSMDPbrpnVTpF0jbsfImmhpM+lWSMAAPlWH/qS9Oqr6X1v2mf6YyTVzzg8VdL+TVdw9xvdvf4hhAMkfZBOaQAApKOqKmn/85/pfW/aod9T0nuZ9lJJA1ta0cxGSerj7s8289k5ZlZjZjWLY8xuAABAJ33+82E5cWJ635l26K+UVD9soVdL329mfSXdIOnM5j5398nuXu3u1QMGDMhLoQAA5NPJJyft6dPT+c60Q3+Wki793SW93XSFzMC9eyRd5O7z0isNAID0NJx7/4QT0vnOtEP/fkkTzewaScdLesnMrmiyzpck7SXpYjObbmYp7QoAANJ13XVh+cEHknv+vy/V0Hf3FQqD+Z6VNNbdZ7v7JU3Wucnd+7j7mMzPH9KsEQCAtDQ82//hD/P/fanfp+/uy9x9irunPOMwAACFpW9faYstQvsXv8j/9zEjHwAAEX3/+2G5fLlUV5ff7yL0AQCI6LTTkvYtt+T3uwh9AAAi6t5dGpiZtebOO/P7XYQ+AACR/ehHYfmPf+T3ewh9AAAiO+64pJ3PufgJfQAAItt4Y2nbbUN7xx3z9z2EPgAABeBrX0vaS5fm5zsIfQAACsCkSUn7/vvz8x2EPgAABWLs2LD80pfys31CHwCAAnFmg2fLrliR++0T+gAAFIiGj9utrs799gl9AAAKRJcu0kknhfZrr+X+yXuEPgAABeTGG5P2Sy/ldtuEPgAABWTTTaUhQ0K74QFALhD6AAAUmJEjw/L223O7XUIfAIAC8+Uvh+WaNdKqVbnbLqEPAECBOfTQpD1+fO62S+gDAFBgzKRx40J72rTcbZfQBwCgAN1zT9L+/e9zs01CHwCAAtS3b9L++c9zs01CHwCAAnXllWFZU5Ob7RH6AAAUqNNOS9oXXtj57RH6AAAUqCFDpG23De2f/1x69dXObY/QBwCggM2Zk7T/9KfObYvQBwCggHXvLk2aFNoXX9y5bRH6AAAUuH32Sdq1tR3fDqEPAECBmzAhaX/2sx3fDqEPAECBq6qSzj47tP/+945vh9AHAKAIXHdd57dB6AMAUAR69JCmTu3cNgh9AACKxMEHS+4d/31CHwCAMkHoAwBQJgh9AADKBKEPAECZIPQBACgThD4AAGWC0AcAoEwQ+gAAlAlCHwCAMkHoAwBQJgh9AADKBKEPAECZIPQBACgThD4AAGWC0AcAoEwQ+gAAlAlCHwCAMkHoAwBQJgh9AADKBKEPAECZIPQBACgThD4AAGWC0AcAoEwQ+gAAlAlCHwCAMpF66JvZbWY2w8wu6cw6AACgfVINfTM7VlKFu4+SNMzMtuvIOgAAoP3SPtMfI2lKpj1V0v4dXAcAALRTZcrf11PSe5n2Ukl7dWQdMztH0jmZl2vNbE6O68SG+ktaEruIEsc+zj/2cf6xj9OxQ0d+Ke3QXympR6bdS833NLS5jrtPljRZksysxt2rc18qGmI/5x/7OP/Yx/nHPk6HmdV05PfS7t6fpaS7fndJb3dwHQAA0E5pn+nfL+lJM9tc0uclnWhmV7j7Ja2ss1/KNQIAUJJSPdN39xUKA/WelTTW3Wc3Cfzm1lnexmYn56FUbIj9nH/s4/xjH+cf+zgdHdrP5u65LgQAABQgZuQDAKBMFE3oM5Nf/rW1/8xsEzP7s5lNNbP7zKxb2jWWgmz/Ts1soJk9n1ZdpaQd+/hGMxufVl2lJIt/L/qY2SNmVmNmt6RdX6nI/DvwZCufdzWzh8zsaTM7s63tFUXoM5Nf/mW5/06RdI27HyJpoaTPpVljKWjn3+nPlNy+iixlu4/N7ABJg9z9oVQLLAFZ7uOJku7K3L7X28y4ja+dzKyPpDsV5q9pySRJs9z9M5ImmFnv1rZZFKEvZvJLwxi1sf/c/UZ3fyzzcoCkD9IpraSMURZ/p2Y2TtInCgdXaJ8xamMfm1lXSb+S9LaZHZVeaSVjjNr+O/5Q0i5mtqmkoZLeTae0klIr6QRJK1pZZ4yS/xdPSGr14KpYQr/pLH0DO7gOWpb1/jOzUZL6uPuzaRRWYtrcz5nLJt+T9J0U6yol2fwtnybpZUk/kbSPmU1KqbZSkc0+fkrSVpK+JumVzHpoB3dfkcUdbO3KvmIJ/ZzM5IdWZbX/zKyvpBsktXntCM3KZj9/R9KN7v5RalWVlmz28Z6SJrv7Qkm/lTQ2pdpKRTb7+FJJ57n7ZZLmSjojpdrKTbuyr1iCkZn88q/N/Zc5A71H0kXuPi+90kpKNn+nB0k638ymS9rDzG5Np7SSkc0+fl3SsEy7WhJ/z+2TzT7uI2lXM6uQtK8k7g/Pj3ZlX1Hcp29mG0t6UtLjyszkJ+m4hhP7NLPOfll0iyAjy338ZUlXSpqdeesmd/9D2rUWs2z2c5P1p7v7mPQqLH5Z/i33lvR/Cl2hXSVNcPf3mtkcmpHlPt5H0u0KXfwzJB3j7isjlFv06v8dyIz1GeHuv2zw2VaSHpH0V0mjFbKvtsVtFUPoS/8ZxXiwpCcyXXIdWgctY/+lg/2cf+zj/GMfF47MtPX7S3q0rZPdogl9AADQOcVyTR8AAHQSoQ8AQJkg9AHIzHpmRlkDKGGEPgAp3Ou73sw8i5//q/8lMzswy99p+DM04n8nUNYqYxcAoCBsKWmtpE8zr1+XdI2kG5usN13S+w1er8ss+2T5HbMb/A6AlBH6AOTu/5kX3cz2ltRP0kNNZwU0s8GS3mnw1vrM77c5e2BmDvb//A6A9NG9D6Cp70t6yt1fbPimmVUpPGjpjQZvr2uyzpJmuvP/2WT7hD4QCaEPQNJ/BvP9WtI4SV9p8H7fzExgP1SYSvVfrWxmlaSx7m7ubpK+IWl1HssG0A507wNlzsy2kHS8QkDXSTq0yVl+raRHFQb7/cjdW3ukcl2W7wGIgNAHypiZdVd4HnoXhcfM3urujc7M3X25mQ1y9w+z2WSW7wGIgO59oIy5+1qFB3TsKOkoSauau81OUsNr9Se3sskqSX9r8HvXZt4DUAA40wfKnLuvyDRXSfqTpAtbWf1fkta08vn22vDMnoF7QIEg9AHUq5O00t3fbmkFM6tTK9foeZw1UNjo3gfQGR05cWC6XyASzvQBNHS6mZ3exjoN/93oKkmZ6/fZ6truqgDkBGf6AOq5pN8qTKnb0s8KNR6YVylpef19+a39SNqmwe8AiMDc23OADgAJM6uU1DOba/lm1kXSxgoHCfzDA0RA6AMAUCbo3gcAoEwQ+gAAlAlCHwCAMkHoAwBQJgh9AADKBKEPAECZ+P+8DwI4P1CUrQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_precision_vs_recall(precisions, recalls):\n",
    "    plt.plot(recalls, precisions, \"b-\", linewidth=2)\n",
    "    plt.xlabel(\"召回\", fontsize=16)\n",
    "    plt.ylabel(\"精度\", fontsize=16)\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_precision_vs_recall(precisions, recalls)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过选择阀值来实现最佳的精度/召回率权衡"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 目标设定为90%的精度，阀值大概在30000左右 , 设置了阀值为30000\n",
    "y_train_pred_90 = (y_scores > 30000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9292811221507891"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5866076369673492"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 获得了一个90%精度的分类器，但如果召回太低，精度再高，也不怎么有用\n",
    "* 如果工作中，需要99%的精度，你应该回应，召回率是多少？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ROC 曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 本质是 真正类率tpr和假正类率fpr（错误的分为正类的负类实例比例）\n",
    "# 与召回/精度曲线非常相似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "\n",
    "fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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551HdHS09swXEXGRUJf+CgJT+gDpwE+HHhBcuPcacKe1dkNlXlR771eNzZs306dPH+655x6GDBnCypUryczMdDqWiIhUkVCX/hvAcGPMVGAg8LUxZsohx1wDZAB3G2M+MMYMquhFtZCvaixevJisrCxmzJjBK6+8Qp06dZyOJCIiVchYa0P7hsakAn2BD62120/09WIat7T3z3iL2/q1OvFwYaikpISVK1fSrVs3rLVs27aNJk2aOB1LRESOwhizonxd27EI+XX61tp91tq5VVH45TTOPz7fffcdXbt2pW/fvuzatQtjjApfRMTF3LEjn1byHRNrLS+99BKdOnVi06ZNzJkzh7S0NKdjiYhINXNF6WshX+X5fD6GDx/OqFGjOPvss8nOzuaSSy5xOpaIiISAK0pfC/kqz+Px0KBBA+69914WLlyoS/JERMKIKzZP1+z+0fn9fqZOncq5555Lly5dmDp1qtORRETEAS4Z6cuR7Nixg4suuohx48Yxe/Zsp+OIiIiDXDHSj9BJ/cOaP38+I0aMICcnh2nTpjFmzBinI4mIiINcUfrya4sWLeLCCy+kbdu2LFy4kDPPPNPpSCIi4jB3TO9roH+Az+cDoFevXjzyyCMsX75chS8iIoBbSl9n9QF49dVXadu2Ldu3b8fj8XDbbbcRHx/vdCwREakhXFH64X5Kv6CggNGjRzN48GDq1q1LWVmZ05FERKQGckXph/P0/qpVq8jMzGT69OncddddfPjhhzRr1szpWCIiUgO5YiFfOE/v33///eTk5LBgwQL69OnjdBwREanB3FH6Ydb5e/fupaCggGbNmvH000/j8/m0d76IiFTIFdP723OKnY4QMh999BEdO3bkyiuvxFpL3bp1VfgiIlIprij9k1LjnI5Q7Xw+H5MnT6ZXr17ExMTw2GOPYcJtikNERE6IS6b33V1+O3fuZODAgSxZsoRhw4bx9NNPk5SU5HQsERGpZVxR+m6XkJBAYWEhM2bMYMSIEU7HERGRWsoV0/tuHOgXFxczZcoUCgoKSEhI4PPPP1fhi4jICXFF6bvNt99+S9euXZkwYQJvvfUWABER+r9KREROjCuaxC0DfWst06dPp1OnTmzZsoW33nqLQYMGOR1LRERcwhWl75b5/SlTpnDNNdfQpUsXsrOzufjii52OJCIiLqKFfDWAtRZjDEOHDiU6Opq//OUveDwep2OJiIjLuGKkX1vH+X6/n4cffpiBAwdiraVFixbccccdKnwREakWrij92mjHjh1cdNFF3H777fj9foqLw2dXQRERcYYrSr+2ndKfP38+6enpLFmyhGeeeYZ///vfxMW5f1dBERFxls7ph1hhYSEjR46kXr16LFy4kDPPPNPpSCIiEiZcUfq14da6mzZtokmTJsTHx/Pee+9x2mmnER8f73QsEREJI5reD4FXX32VM888kwcffBCA9u3bq/BFRCTkXFH6NVVBQQGjR49m8ODBtGvXjiuvvNLpSCIiEsZcUfo1caD/1VdfkZmZyfTp07nrrrtYsmQJp556qtOxREQkjLninH5NVFRURGFhIQsXLqR3795OxxEREXHJSL+GDPX37NnD9OnTAejcuTNr165V4YuISI3hjtKvARP8H374IR07duSGG27gp59+AiA6OtrZUCIiIgdxRek7yev1MmnSJM4//3zi4uL47LPPdO5eRERqJHec03dooG+t5be//S3vvvsuw4cP56mnniIpKcmZMCIiIhVwR+k7xBjDlVdeyZAhQxg+fLjTcURERI7KFaUfyoF+cXEx48aNIyMjg1GjRjFs2LAQvruIiMjxc8U5fROi5ftr1qyhS5cuPPnkk/zwww8heU8REZGq4oqRfnWz1vLiiy9y0003ER8fz9tvv81FF13kdCwREZFj4o6RfjW/flZWFtdccw1dunQhOztbhS8iIrWSRvpHsWvXLtLS0jj77LOZN28eF1xwAR6Px+lYIiIix8UdI/0qHur7/X4eeughTj31VJYvXw7AhRdeqMIXEZFaTSP9Q+zYsYMRI0Ywf/58LrvsMk4//XSnI4mIiFQJjfQPMn/+fNLT0/nwww955plneO2110hNTa2aFxcREXGYK0b6VbX3/meffUb9+vVZtGgR7dq1q5LXFBERqSlcMdI/ET/++COffPIJAOPHj2f58uUqfBERcSVXlP7xTu/Pnj2bjh07Mnr0aHw+Hx6Ph7i4uKoNJyIiUkO4ovSPVUFBAVdffTVXXnkl7du3Z968eVqZLyIirueKc/rHYteuXZx77rl8//33jB8/nnvuuYfIyLD7MoiISBhyRdsdy9779evX5/zzz2fatGmcf/751ZhKRESkZgmL6f09e/YwdOhQfvzxR4wxKnwREQlLrij9o43zlyxZQnp6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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_roc_curve(fpr, tpr, label=None):\n",
    "    plt.plot(fpr, tpr, linewidth=2, label=label)\n",
    "    plt.plot([0, 1], [0, 1], 'k--')\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "    plt.xlabel('假正类率', fontsize=16)\n",
    "    plt.ylabel('真正类率', fontsize=16)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_roc_curve(fpr, tpr)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9590312638413596"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算曲线下面积AUC，虚线是随机分类0.5到1\n",
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "roc_auc_score(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 召回率TPR越高，分类器的假正类FPR就越多\n",
    "* 虚线表示纯随机分类器的ROC曲线，好的分类器应该远离这条线，向左上角\n",
    "* 是使用精度/召回率 PR曲线，还是使用ROC，关键在于 正类非常少或者更关注假正类而不是假负类，选择PR，反之ROC\n",
    "* 例如：前面例子ROC曲线很不错是因为跟负类 非5 相比， 正类 数据5 数量真的很少"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练随机森林分类器，比较SGD分类器的ROC曲线和ROC AUC分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 获取训练集中每个实例的分数\n",
    "* RandomForestClassifier 没有descision_function(),但是拥有dict_proda()方法，sklearn中分类器都有这两个中的一个\n",
    "* dict_proda返回一个矩阵，每行一个实例，每列代表一个类别的概率，比如这个图片 70%是5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "forest_clf = RandomForestClassifier(n_estimators=10, random_state=42)\n",
    "y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n",
    "                                    method=\"predict_proba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.2, 0.8],\n",
       "       [1. , 0. ],\n",
       "       [1. , 0. ],\n",
       "       ...,\n",
       "       [0.8, 0.2],\n",
       "       [1. , 0. ],\n",
       "       [0.2, 0.8]])"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_probas_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 绘制ROC曲线，需要决策值不是概率，直接使用正类的概率作为决策值：\n",
    "y_scores_forest = y_probas_forest[:, 1] \n",
    "fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.8, 0. , 0. , ..., 0.2, 0. , 0.8])"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n",
    "plot_roc_curve(fpr_forest, tpr_forest, \"Random Forest\")\n",
    "plt.legend(loc=\"lower right\", fontsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9927612311885732"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Rand 比SGD 好很多，ROC AUC的分数也高很多\n",
    "roc_auc_score(y_train_5, y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9842243645924628"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 再看一下 精度和召回率 也很高\n",
    "y_train_pred_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3)\n",
    "precision_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8286294041689725"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 选择合适的指标利用交叉验证来对分类器进行评估\n",
    "* 选择满足需求的精度/召回率权衡\n",
    "* 使用ROC曲线和ROC AUC分数比较多个模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多类别分类器\n",
    "* 尝试5 之外的检测\n",
    "* 多类别分类器 区分两个以上的类别\n",
    "* 随机森里和朴素贝叶斯可以直接处理多个类别\n",
    "* 支持向量机svm和线性分类器只可以处理二元分类器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 解决方案\n",
    "1. 将数字图片分类0到9，训练10个二元分类器，每个数字一个，检测一张图片时，获取每个分类器的决策分数，哪个最高属于哪个，称为一对多OvA\n",
    "2. 为每一对数字训练一个二元分类器，区分0，1 区分0，2 区分1，2 称为一对一OvO策略，存在N个类别，需要N*（N-1）/2个分类器，最后看哪个类别获胜最多\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 优缺点\n",
    "* OvO 只需要用到部分训练集对其必须区分两个类别进行训练\n",
    "* 对于较小训练集合OvO比较有优势， 大训练集合 OvA 速度快，所以OvA更常用，比如svm 在数据规模扩大时表现糟糕\n",
    "* sklearn 检查到使用二元分类算法进行多类别分类任务，会自动运行OvA，SVM分类器除外"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.fit(X_train, y_train)\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-130925.47994863, -489285.03329748, -233335.03268504,\n",
       "        -301491.01792999, -504430.31349679,   42217.83953346,\n",
       "        -709294.90235509, -246867.76598493, -579820.13951646,\n",
       "        -562334.49609594]])"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 内部实际上训练了10个二元分类器，获得图片的决策分数，然后选择了分数最高的类别\n",
    "# 返回10个分数，每个类别1个\n",
    "some_digit_scores = sgd_clf.decision_function([some_digit])\n",
    "some_digit_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argmax(some_digit_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 目标类别列表会存储在classes_这个属性中，按值大小排列，\n",
    "sgd_clf.classes_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.classes_[np.argmax(some_digit_scores)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用OvO策略，一对一或者一对多\n",
    "from sklearn.multiclass import OneVsOneClassifier\n",
    "ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5, tol=-np.infty, random_state=42))\n",
    "ovo_clf.fit(X_train, y_train)\n",
    "ovo_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ovo_clf.estimators_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用随机森林\n",
    "forest_clf.fit(X_train, y_train)\n",
    "forest_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0. , 0. , 0. , 0.2, 0. , 0.8, 0. , 0. , 0. , 0. ]])"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 随机森林直接将实例分为多个类别，调用predict_proba()可以获得分类器将每个实例分类为每个类别的概率列表\n",
    "forest_clf.predict_proba([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评估分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.84433113, 0.86754338, 0.86507976])"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用交叉验证评估SGD的准确率\n",
    "cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.91076785, 0.90694535, 0.90883633])"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将输入进行简单缩放 ，可以得到准确率 90 %以上\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
    "cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 错误分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 项目流程\n",
    "1. 探索数据准备的选项\n",
    "2. 尝试多个模型\n",
    "3. 选择最佳模型并用GridSearchCV对参数进行微调\n",
    "4. 尽可能自动化\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 确定了一个相对合适的模型，进一步优化，分析其错误类型\n",
    "* 查看混淆矩阵\n",
    "* 使用cross_val_predict()进行预测\n",
    "* 调用confusion_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n",
      "/usr/local/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/stochastic_gradient.py:128: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.\n",
      "  \"and default tol will be 1e-3.\" % type(self), FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[5727,    3,   19,    9,    9,   53,   52,    9,   37,    5],\n",
       "       [   2, 6483,   44,   36,    6,   44,    9,   12,   96,   10],\n",
       "       [  54,   40, 5308,  102,   87,   27,  106,   56,  163,   15],\n",
       "       [  53,   39,  137, 5343,    4,  229,   37,   59,  137,   93],\n",
       "       [  22,   30,   35,    9, 5357,   11,   59,   29,   83,  207],\n",
       "       [  82,   46,   34,  189,   67, 4592,  110,   28,  171,  102],\n",
       "       [  34,   23,   41,    1,   40,   90, 5635,    7,   47,    0],\n",
       "       [  24,   23,   67,   24,   51,   13,    7, 5778,   15,  263],\n",
       "       [  49,  158,   66,  159,   14,  163,   58,   24, 5014,  146],\n",
       "       [  42,   32,   27,   92,  154,   27,    3,  202,   76, 5294]])"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n",
    "conf_mx = confusion_matrix(y_train, y_train_pred)\n",
    "conf_mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib的matshow 函数来查看混淆矩阵的图像表示\n",
    "plt.matshow(conf_mx, cmap = plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 看起来不错，大多数图片都在主对角线上，说明它们被正确分类\n",
    "# 数字5 看起来比较暗，说明1. 数字5图片较少  2. 分类器在数字5上执行效果不如其他数字上好\n",
    "# 假设把焦点放在错误上，为取得错误率，而不是错误绝对值，需要将混淆矩阵中每个值除以相应类别中的图片数量\n",
    "\n",
    "row_sums = conf_mx.sum(axis=1, keepdims=True)\n",
    "norm_conf_mx = conf_mx / row_sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 用0填充对角线 只保留错误，重新绘制\n",
    "np.fill_diagonal(norm_conf_mx, 0)\n",
    "plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 每行代表实际类别，每列代表预测类别\n",
    "# 8，9列比较亮，说明许多图片被错误的分类为数字8，9\n",
    "# 类别8，9行也偏亮，说明数字8和9经常会跟其他数字混淆\n",
    "# 有些很暗，比如行1，大多数数字1都被正确的分类，一些和8混淆\n",
    "# 5和3是错误最多的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 结论\n",
    "* 改进数字8和9的分类\n",
    "* 修正数字3和5的混淆\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 如何优化分类器\n",
    "* 尝试多收集这些数字的训练集\n",
    "* 开发一些新特征来改进分类器\n",
    "* 优化分类器算法\n",
    "* 使用pillow或opencv对图片预处理，让显示模型更突出\n",
    "* 分析单个错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAHTCAYAAAD/OsuWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsnXecjNf3x98ji9UShLW+LCJES7QEq6+SENFWLFIkJGpEsFLUsFlk1SUkSCIIiV6WKNFLQpToUVZb27TF6lvd3x/P714z28uUXe779ZqXnZln5h4zc5/z3HPP+RyTEAKNRqPRaDT2JYejDdBoNBqN5mlEO2CNRqPRaByAdsAajUaj0TgA7YA1Go1Go3EA2gFrNBqNRuMAtAPWaDQajcYBaAes0Wg0Go0D0A5Yo9FoNBoHoB2wRqPRaDQOwMlB42r5LY0mMSZHG5BB9HzWaBKT6nzWK2CNRqPRaByAdsAajUaj0TgA7YA1Go1Go3EA2gFrNBqNRuMAtAPWaDQajcYBOCoLOt0EBwdTuXJlALy8vJg4cSKFChUC4JlnnrG7PbGxsQDs27ePP/74A4ApU6aoxwE6duyIr68vABUrVrS7jZrMI7/PqVOncuvWLYvnNm/eDMDBgwfx9PTkm2++AeDll1+2r5FPCCEhIQCsW7dOfZZt2rTh3XffpXHjxo40LVvw8OFDBgwYQKNGjQCoVasWpUuXBsDZ2dmRpmmSwSSEQyoI0j3ogwcPmDFjBgD+/v5cuXJFObXPPvsMLy8vAJ5//nlMJttWc1y+fBkfHx8AfvzxxxSPlRNgz549FC9e3KZ2mRMREQHAjh07WLduHefPnwfgn3/+sbhIAHjuuecA8PT0pGTJkgB8/fXX5MyZ0272muPv74+3tzcA1atX54cffqBu3bp2tyM6Opo+ffoAMH/+fIvnhBCJfmclSpQADAdStWrVjAz51JYh9e3bl9mzZwMk+lw9PDzYunVrZod44rl9+zZeXl7qwhBg1KhRAIwePdrq4z18+JCJEycCcPPmTfX4kSNHAGPuJsTb25tSpUpZ3ZYsSqrzOds4YHPu3bvHzJkzWbp0KWCsQCSdOnVi+PDhGT0BpsqhQ4do164dYWFh6rFq1aoB0KRJExo0aKAenz9/PmvXrgXgv//+o1KlSjaxKSnkqrxt27YpHlesWDE1ecwdc58+ffjhhx9sZ2AS/PvvvwDUrVvXwpZcuXLxv//9D4D33nuPTz/9FABXV1eb2hMaGkqbNm0AOHr0qMVzL7zwAhcvXkzydY0bN2bjxo0A5M6dOz1DPlUO+MaNGwDMnDmTsWPHEh0dDUCFChUIDAxUxzVt2tTCqdiL6OhoC8diTt68edWFa1bi8uXLfPvttwBMnz6dAgUKAHD16lXy5Mlj1bEOHTrE+++/D8Dp06fT9Jq8efPi7e2tIhy2plSpUiqyYo67uztubm4Wz8lzekhICHv27LHGRb+uA9ZoNBqNJiuSbfaAzcmfPz9ffPGFCg+uW7eOZcuWAbBmzRo2b96sQsT9+/e3yph37twBjBVleHg4tWvXBoyQilxlJtxncXFxUSvgxYsXK5vsgQw5P/PMM9SsWZNXX31V2dSyZUt13IsvvsiaNWsA2L9/P3PnzgVg4cKFtGrVitatW9vN5oCAAIBEIfKYmBiCgoIAGDt2rMXKyZaULFlSfTb79u2zeK5du3bK3suXLzNgwAD13M6dOzl16hSQdBhOY7Bo0SLgcZhURjm+//57Xn/9dXVcq1at7GbTX3/9xZdffgkYc/6///5L8jhXV1cmTJgAQNeuXe1mX2oUL16cuLg4df/u3buAERa29jZOzZo11bZBgQIFcHKydCdynv73338sXLgQgL1797J8+XIGDRoEoPJ4bEXHjh0JDQ0FjJWtm5ub+htQ980JCQkhJCTELtte2TIEnRLz58+nW7duNG/eHMBqoSsZiipSpAiTJk2iV69egHExkBw//fQTvXv3BqBbt2788ssvVrElLRw4cAAwfvCfffZZml5z/vx5mjZtChg/wkGDBjF58mSb2ZiQN954AzBOgvL769q1K7/++qsKqQMULFgQME4qco/dkZw9e5YKFSpYPHbo0CEg3Q74qQlBe3t7M3XqVHXfw8ND7Sdu3ryZYcOGAcaJ/fbt21YyM3kuXLgAwKuvvqpyNYoVK0bDhg3VMeb7/gcPHmT79u0AHD58OEskWd68eZN+/fqxfPlyAOLi4tQCxN/f3yHJqmCE8mWoevny5ZQrV449e/YAULRoUYfYlBTS4YaFhfH3338n6ZzTiQ5BazQajUaTFcmWIeiExMbGqqu+3r17kzt3bnr06GGTsZ577jmaNm2a4soXjKtRmbUN9g9F1qpVy+LflLh8+TIAI0eOVKGZvHnzWlz92wOZUX7x4kWaNGmiHu/QoYO6Oj1w4ACRkZEAREZGZokVsAyvSVxcXHj22WcdZE324MqVKxbZziNHjiRXrlyAsbUgn1u9erVd7JEZ7GvXrrVIpEyIrC7w9vYmKioKMLKBHcXDhw/57rvvAJg8eTLXr19Xz9WuXVtFsOy9+g0LC+Pw4cMATJw4kd27dwNQpkwZhgwZkqVWvmB8n//88w8AS5YsscbqN01kawcsf2z9+/dnyZIlAFStWhUfHx/at29v1bHkXkVYWBh58+a1eC4+Ph6Ab7/9lvHjxwNGuOrBgwfqmPPnz6vM2KZNm/LMM884LCQkuXPnDosWLVIlClevXlXPvfLKK1b/DFOjTJkyFv9mdeRJJWG2+HvvvUfZsmUdYVK2YfHixcrJNmvWjPr169OxY0fAyD6XJ0BbVTMkRGarJ3S+svZ7y5YtLF++XIWdr1+/zgcffACg9AnswdmzZ7l16xazZs0CYP369RbzFlDbY23atLFrKaG8OJE5OOaZ7DJPZtasWTavXkgPspLG399f7Ut36tTJbuPrELRGo9FoNA4g2yZhbdy4kS+++AIwVqWyNnT48OHprb3MNDIbcsiQIWl+Tfv27dXKqVChQna1ecWKFYAhfnD9+nWLUKC8+vv222954YUX7GaTOQ8ePGDdunWAEUn4+++/Wb9+PWBkRMtsy8OHDzss1PvLL7+oLF4pElGsWDEAdu3aRfny5TPytk9NEtbChQvVyq1bt24EBQWp7RKTyaSEdRYvXmxFM9OGTPr67LPPVBXDrVu3yJEjB926dQMMNT6ZsChD57ZEJonVrFmTYsWKWawuzenfvz9TpkwBSJSVbEvCw8OVApzcIipSpAhgVKnUrFkTcIxqYXKEhIRQv359wKgLlqthK5LqfM62IejvvvtOpdgfPXrUbjH7pPjzzz8B4wQsVV769euX6Ljvv/8eMPYxV69erfa3Zs+erbIErV0sL5GF8qNHj1YOWIbOZUj93XffVaU9jpwoN27cSBQGknZFRETw1ltvAdjV+c6fP59t27axadMmIPEeJjzO4j516lRGHfBTg/y9S4KCgjBfDEg1pcjISJX1bi/k3u7+/fst5Ed/++03unTpYldbJFKkJD4+nuDg4GSPO3DgAO+88w4ALVq0UBcMtnbGixcvVo5XIkPSPj4+KrP8888/T1Qx4Cj8/f1VzovcwrQ32XYFvGbNGnWSrlGjBj/99BPgWB3ec+fOUa5cuVSPGzp0KNu2bVOlQgBfffUVgFKxsSZ37txRdslJIRFCqOSnnj17Wn3sjBAeHs4rr7wCkEiJaN68eXz44Yd2sWPBggVqfzyhg0hKilLi5OSkEmNkrXoaeWpWwEkh9wll9ANg1apVqaq52YoDBw6oeSn3fmWt/4svvqgSK5s2bUrp0qVp1qyZzW0KDg7mww8/ZMeOHeoxubqU+71SUS4uLk5drI4aNSpNCZkZJSYmhhEjRgCo1blUj7t06ZI6Lnfu3HTp0kXVzTuqTl6ufmXy3d69e20xjC5D0mg0Go0mK5JtV8DwWOygR48eSnmoR48eDBw4kBdffNEaQ9iM6OholXU3a9YstV9y+PBhdVVmTeRY06ZNs3hcCKFWx3369OHtt98GHJ+JLEujfH19LRSvihYtqkL+NWrUsMnYu3btAkixA0++fPlUyLlcuXJMnTo1kYIXGKFzmZWaI0eq17tP9Qr4xIkTALRu3dpCo3fhwoUqrOoowsLCWLZsmYXuvFyFXrt2jdjYWJWx3bFjRz7//HPANltK8fHxSrEOUBEhuQKWz1WpUkUd8/rrrxMQEICHh4fV7UkOGW27e/euamYSEBDA0aNHlUZ127Zt1crZnqFpb29v/P39Va6BDfZ/IS3zWQjhiJtVefjwoRg1apQYNWqUKFasmChVqpQICQkRISEh1h7Kqjx8+FA8fPhQNGzYUJhMJmEymcSECRNEVFSUiIqKssmYCxYsEJ6ensLT01M0bdpUVK9eXWCcQAUg3NzchJubmzh79qxNxs8IJUuWtLCxRYsWokWLFuLOnTs2GS8sLEyEhYWJatWqqe8lX758onjx4mLy5Mli8uTJiV6zfv16UaVKFVGlShX1Gnm7fPmyuHz5clqGdtR8zFLzedOmTSJHjhzq5ubmJs6cOSPOnDlj7aGswtmzZ8XEiRNFnTp1RJ06dYSzs7OoWrWqqFq1apaxeejQoSJfvnxi7ty5Yu7cuQ6zIzIyUnz++eeiaNGiomjRogIQ3bt3F927dxdXr161mx1LliyxOKd4eXmJ4OBgERwcbM1hUp07OgSt0Wg0Go0jSIuXtsHNZpw5c0aUKVNGtG3bVrRt29aWQ1mNtWvXWqyYbt68KW7evGmXsR8+fCjWrFkj1qxZI1555RVlwxtvvJHWVZvNmTdvnujRo4fo0aOHxVXrkSNHbDpuSEiIaNiwoWjYsKFYs2ZNqsdPnz5dTJ8+Xa+ArYCPj4/w8fEROXPmFICoW7euqFu3rlXe++HDh1Z5n+RYsmSJKFiwoChYsKB44403bDpWWrl//77o0aOHKFu2rChbtqyIi4tzqD1BQUEiKChING3aVM2TkiVLiuPHj9vNhiVLlqiIn/l5xd3dXSxZssQaK+JU50623gNOjnfffZdt27YBhgJVvnz5bDlcpnn06BHu7u6AIfIuu4jYulNIQnbt2qWaR5w5c8buDSRSYsOGDYBlZ5wjR46oXsxZASmHmrCEKjw8HEhT/+Knag9YlhECak8wIe7u7uzfv1/lSCxbtizFvfm0ULNmTdU8wcvLi8aNG1O4cOFMvac5EREReHp6AsZv1Pz/6Ug6dOjAqlWrAOM8IzukOZK4uDiV5b5x40ZKly6dbJ9tWyBzDfz9/VUmtJSklEyePBlvb++MvH2q8/mJccCyXeDkyZMZM2YM48aNAx6X91gbqf96/fp1pQudmUlcp04dwCh9cJQDBlTXobZt21KkSBGuXbtmdxuSQmpB//PPP6oR+uHDh60mFiKbcZuXYk2YMCFdZW3y4kBKjkq0A07MgwcPVBu/UqVK4e/vn+Rxly9fpkSJEqrk6/nnn1fJWi4uLhky9ty5c0orfufOnRQrVkw55ObNm6t2nXnz5lWJQanVxV+7dk2VKn3xxRfqxD5ixAh8fX0zZKc1WbZsGSNGjFAlQjExMXaVqUwJWeM8ZMgQpk2bprQUtm7d6pBk2r1797Js2TJ1QR0SEqIWSEuXLk2P5oQuQ9JoNBqNJivyRKyAz507p0o9tm/fjo+Pj0ptT0PpR4aQq5xWrVrx0ksvAUZoS66Gvb2909wjdPv27SpsWb16dSVEYA+Ju4TI0oHy5ctz7949fHx8AFR/Vntz9+5dmjdvriIOISEhKqqRHunPlIiOjuaTTz4BjBIOGdbeuXNnmtW2NmzYoNSdzNWT3NzclKpTGiIaT80KePTo0Wpl6OXllaLkZO/evfn555/VfRlGzYxAh1SBO3bsGMuWLWPNmjWA0TzeHLkC7tChAwcOHFCRkoRERESo5jClSpVi6NChALzzzjsqYpNRgoODVVmejJSlhcjISNWpa9CgQcTFxfHRRx8BRq9yW50bM8qlS5eoVq2aimZu2bJFyX06krp161qEpWUvYxmVS4EnV4ry3r17zJ49GwA/Pz8L2bMRI0bY9cclwzrm+qyLFy+mfv36qsZW7gmB0Xw8JiZGfZFDhw5VYecXX3zRIY5XsnPnTuCxHu6xY8dsPuajR48snNb58+dVh5n9+/fTvXt3mjdvDhha3x9//LFVx79586ZFXeX58+cB+Pjjj1WdYKtWrcifP7+qN//3339VqzcwlLKSahy/aNEih2wlZHVkEgoYYb3nnntOhfBr1qyp5FGff/55xo8fr36XgYGBqkvXo0ePMjy+DCnXqFGDGjVqKMWzsLAwjh8/DhhzQWoNrFq1ihs3bqiL7bNnz1rIjRYuXJj+/fsDxgVDRsPjSSHDx2BIOQ4ZMsQir0WGcOVveN++fYBRpxwUFKSO++ijj5Qcrq3PjydOnFAXNWm9eD9z5oxDWzsmx969ey22wOR2SRoccKpkrUsgjUaj0WieErJVCFr2112zZg1TpkxRWsoVK1bk66+/BqBz5852Wf3K1U5gYKBSarp9+7YKj6XEa6+9RmxsrNJKBShZsiRg/N/srY8qr/j9/f1VswGZOCT7jsoQvy2YMGFComQ5mehQokQJihcvruyIj49Xwu7WIi4uTiktyUYVCSldujQ5c+ZUK/WIiIhktaDd3NzUamjAgAHpSXZ5akLQDx48UApOK1euNN7k/89FJpNJff916tThwYMHqhsWwP/+9z8AC7UsWxMVFUVUVJRqDGHPJhH//vsvw4cPB4zGL87OzmolLiMygFJik9smd+7cUdnlYWFh5MuXz26RwXHjxjF9+nTAWEEmp6wnhFBzTiaJSSXAnTt3Zom+2uZdk0JCQqwags7SDvjixYvqy9mzZ4+ahNHR0bRv31453VdeecWurbeSQwih2oaBcTKXmZFSPjEpSpQoodqe2cL5rly5UjmtokWLqr2qTZs2sWLFCs6cOQOQSEqxUaNGqtWeLbojyfB2jRo1Ug0nyhIBmY1obWSorkWLFpw9ezbV44VI3IyhXbt26j3S2YRB8tQ4YHhchrRq1Sr69evH/fv3ARJ9rgk/a9nGU5bMPQ3Iz2rgwIEEBwezZcsWwMislw1L8ubNS506dVQFyMaNG1UzBnuX682ePZu+ffsC8Omnn6o98eeff16dbwCmTJmiZCrBOBfK/5ujuybJto5Tp05Vj02aNClRmWEK6CxojUaj0WiyIllyBSzDfM8//7wKSzVp0kQlxLi5ufHWW28lGwLMSsTExABw//59ZsyYARjhK39/f5XF+c033yghd1tQo0YNFe5+7rnnLJKFzFcX5qG/N954g+nTp5M7d26b2SUzO+vXr59s8X2hQoX4448/VOMFW/VLlly6dEm1tjx//rzqE1qtWjW1mgAYPHgwf//9N2AkZrRv315FLzIRjcn6P+ikyfRJ5PLlyyraYr4189NPP3Hnzh0VlhwxYoSq4c1Kzd3tyaNHj1S/8Z49e6p61SZNmvD666870jRFVFQUlSpVAow5Zb6llFDoQiYp9ujRg969ezs87Lx37146d+6stjjc3d1Vs4Z09p3P3iFojXWYN28ev/76K4BFH9Fy5cqpvQ0w9tJtJVySEmfPnqVXr14WtskM0507d1p9zzcL89Q6YM2Tx+nTpwFUtQoY4dzSpUurqpA8efLw6aefAo/39h2BFN8AIxfG3d1dhaAzke2sHbBGk43QDlijsSPSyQ4ePFhFWAcNGmSVEiP0HrBGo9FoNFkTvQLWaLIOegWs0Tw56BWwRqPRaDRZEe2ANRqNRqNxANoBazQajUbjALQD1mg0Go3GAWgHrNFoNBqNA9AOWKPRaDQaB6AdsEaj0Wg0DsDxLYRSICgoyKITheTIkSMWXYPatGmjtJSLFi1qN/s0tmfEiBGMHTtW3XdyclIdpho0aOAoszQaTTr46KOPAJg7dy6A0qyeOXMmL774osPscjR6BazRaDQajQPI0kpY//zzD/Xq1Uv+TcwaeJcuXRqAqlWr0rJlSxo2bAjAyy+/nFlb08WuXbsAQ4j89OnTVKxYEUB12DFH9sjs0KFDpsfdsWMHPj4+6u/k8PDwoHHjxsk+P3r06EzbkllOnjxJmzZtAKMBdlxcnMXzI0eOBFD/X1siexYHBgbyyiuvqK4oP/30k2oYUbJkSYYPH66apGcCrYSVBZDzx3xOJcWoUaOArDFnsjre3t4A7N+/n2PHjnHv3j3AaLqybds2ANXxypY8ePAAgPj4+ETPFShQwNrDZe9mDOYO+P3338fZ2RmA4OBgNm3aZOGAE/Lcc88B4OnpqTr8WLPBs2wefvr0adXg/sMPP+TatWvKJvNWf0n9XaRIEQA2bNjAq6++mil7rN2a0cPDQ4V67UFsbCyDBw8GYNmyZVy9ejXJ45555hkVxnr//fdtatNHH33EggULAGPCPvPMM4kuBiROTk7kyGEElAoVKsSgQYMAo62jbKWYBp5qByxPjn5+fpw9exaAxYsXA1CmTBkAtmzZYtOQ5ejRo9m5cyeQ8oWsOQ46hwIQFxenug6dOHGC0NBQ7ty5AxjzSD5XpEgRtm7datO2p2nlxIkTvPHGGwBcuXKF33//HYAuXbpYfay4uDh1fl6yZAmTJk0CIDw8PNGxcs5+9dVXuLi4WGP47O2Aw8LCVBu9zz77jHz58gHGhxoTE6N++GvXruWPP/4AYPPmzeoDl7zyyisAHDhwgFy5cmXa+FOnTvH2228DcObMGYsLAfO/ixQpkuTq9tq1a6xevVod27t3b2bOnJkpm8yv1lNa4QJpPsGMGjXKLlf3gYGBzJ49G39/f/WYdFrNmjVTkwZg4MCBqoOJrSlevDhXrlzJ1HsUKlRI9blNgyN+ah3wmDFjVDu448ePq8dbtmxJaGgoJ06cAODtt99Wx1mTJk2aAMnPCbnalZivjO01T8Bw9v/995/qATx9+nTVP71o0aK0aNFCLT6aNm3KvHnzAPjjjz9YvXq1iiw5kgsXLlClShUAoqOj1bmvd+/eVhtj4cKFAAQEBLBixYokjylUqBCPHj0CIGfOnMpvFCtWjMDAQJ599tnMmqG1oDUajUajyZIIIRxxsxl37twRXbp0ESaTKdFt69atVhnjtddeExhX/cJkMqm/O3ToIGbPni1mz54trl+/nuzrr127JsqUKWPxHlkBDw8PZRMgtm/fbtPxzpw5I86cOSNKlixp8T0tWbJEXLt2TVy7dk107txZmEwmUaFCBVGhQgVx7tw5m9pkjqurq8XnUaZMGdG3b191K1GihChRooTFMUndihUrJooVK5aWIR01Hx0yny9fviwuX74sqlWrJnLkyCFKlSolSpUqJSZPnizu3r0r7t69KyIjI0XDhg1FgQIFRIECBcTmzZszOlyybN++PcnvzcPDI8ljEx4/atQoq9uUkAcPHogHDx6IoUOHCpPJJFxcXISLi4vo16+f2LZtm9i2bZs6NioqSkRFRYlBgwaJ4sWLi+LFi4t58+bZ3Ma00rNnTzXXCxUqJM6ePSvOnj1rtfefMmWKKF++vChfvrwwmUwiX758Il++fKJGjRpiypQpYsqUKWLZsmXi+PHj4vDhw+Lw4cPi5MmTFufjuXPnWsOUVOdOli5DSg8TJkwAjDj/4cOHLZ6TIRkrxfUt3ss8xDx06FBKlSqV6msjIiKIiIhQ+7YynO0IduzYocJv5mzfvh0PDw+bjn379m0AtW+eO3duAFq1asUHH3wAwOrVqylVqpTaYrBnycKcOXNU+GrFihVcuXKF1157DTD2h319fQGIiYmhW7dubNq0Kcn3qVSpkn0MzkZcuXKFN998EzAS3QYPHkynTp0AqFWrltrH7NSpE3/99Rft2rUDoHnz5la3xTzfYceOHep3n9TvP6mkLFuHn8+ePUu/fv0A+Pfff5k0aZJKakpIaGgon3zyCQC3bt1Sv0l7J6OaExQUxI8//ggY8ygoKEjt9/7yyy8qt8darF69Wp0/XnvtNRVKTiqh959//gHgzz//VI/lzp2bYsWKWdWm5NAhaI1Go9FoHEFalsk2uGWamJgYsXbtWrF27Vrh7u4ucubMKXLmzKlCG/J+kyZNxK5du8SuXbusMaxV6N27t0XoesSIEXYdX4bREoacPTw81HP2ZNmyZcLX11fs3r1b7N69W7z55psWIemhQ4fa1Z6kCA0NFRUrVhRvvvmmePPNN4UQQly9elVcvXpVfPvttyJPnjxJhjGdnZ3Fxo0bxcaNG9MyjKNDyTafz7dv3xa3b98W1apVU9/vwIEDRWxsrDrm3r17wsPDQ3h4eAiTySRatGghjh8/Lo4fP56eoTLE9u3bxahRo8SoUaMs5kfCuWJ+sxUy7Pz666+Ldu3aiXbt2omIiIhEx8XFxYm4uDixbt06UaxYMTFu3Dgxbtw4cf/+fZvZlhrx8fFi0aJFYtGiRaJEiRLquy5XrpxYtGiRw+yS7N69W7Rt21bkzp1b5M6d2+J8/NVXX1lrmFTnTpafsJL4+Hhx7NgxcezYMTF69Gjh7u5uEbM3d7xvvPFGon2RrMDJkyfFyZMnhYuLi8iRI4eoVKmSqFSpkl0nyqhRo5Lc65LO11FER0cr52b+fZYpU0acPn3aYXaZs379ejF27FgxduxYceXKFdG4cWPRuHHjJE/KTZs2FU2bNk3v3pajHanN53NoaKgIDQ0VJpNJeHt7C29vbxEaGiqEECIwMFAEBgaK6tWrq+/f3d1d/Pfff+kZIlMk52RTutlq3hw4cEAcOHBA1K9fX0RERCTpfO/evSu+/PJL8eWXX4rixYuLdevW2cSW9DJ+/HiLedyzZ0/Rs2dPcenSJbvacefOHfHOO++Id955R1SvXl3d8uXLlyhHSH6fbm5uomnTpmLp0qVi6dKl4vLlyxkdPtW5o0PQGo1Go9E4gCxdBwxGUgFAr1692Lhxo+Wb/L/t7u7uNGvWDDDqBrOiRvClS5dU0smpU6cwmUy89957AErswZYkV+dozxrGlNi5c6dFMpgUXggICFB13FmJGTNm0L9/f4vHpJLO22+/zeTJkwEoXLhwet72ia8DlkImmzdvVnrATk5O7N69m86dOwNGglbr1q0BmDZtGi/1Dz8qAAAgAElEQVS88IK17U1EanXAqWGuMGeP+bRnzx4ABgwYoPTvZ86cqRQBHUlQUBC1atXixo0bgFGDLL/rnDlz2tWWs2fPJivA1LFjRwv1q19++QVILGr0v//9T52DvvzyyySTVpMhewtxXL58mZYtWwKWxfkSmaHaokUL8ubNa0XzMs/KlStZtWqVUqIJDg4mIiICeKyEJW329PRUspS2yJgdPXp0ktmb9sh0Tgvbtm2jS5cu6vOBxyfEIUOGEBYWxrRp0xK9rm7dukyePJk8efLYzVbJggULVKalRMqOnjp1KqNv+8Q7YHOkM/7mm2+YPn26yop/7733mD9/PoBSF7M1aVWSk4IcHh4eyUq/2lJFLj4+Xn1eAH369KFt27bAYxnczZs3A3D37l31umrVqllUELz66qvUrl0bsL4E47lz56hVq5b6PuvUqaPOax06dFAXV/bg+vXrqpnLwYMHLaoYKleujJPT40Igc9GddevWKQEdqcYGRob0kCFDAPjiiy9S8zvZ2wGPHz9e/WeTYsCAAepvd3d3wDZyZulBliVJpaukpCiLFClCRESEWsFbW5YyIcmVGsmrdkevgN9++21WrVqVodf26dOHiRMnAiilNHtw+/Zt9ZnKsjdZTjFlyhT69u2bkbd9qhyw1EeXCkiytO/vv/+mbNmygPUlVpNDOtHkVjepRYqaNGli4Yjlha21HLFUbPrhhx/o37+/UvQrVqyYksWVK2Ep85hQyenQoUNcuHABMKR0pfOZNWuWeo21Pu+FCxcye/ZswNB/jomJUc85Ozur8/qwYcPstiqOiYlJlxKi1IveunWr+tx8fHyUTO7y5ctT0/HXSlgajUaj0WRFsvQK+KuvvlKrmyTfxGwFKfc+3N3d6dGjhwo1SBEOe1G5cmXgsUa0vN+wYUM8PT0BI1QZERGhVn3jxo1T/5dGjRpleB8qJeR7+vj4pKh364jVcEor4GLFillcId++fdsitAaPi+llSM1eBAQEANCtWzciIyPV487OzqxcuRJA7funkadqBRwdHQ3AxIkTWbNmDQcPHlTPSWH80aNH26JLjdVJrhuZNbZ5jh07pnTS582bR+HChVW3t44dO6r8l+LFi6f5Pe/evas0tfv06aN+y+n8vaaJc+fOqa24lStXsnz5ctUNqU+fPmp7yd77wxnh1KlTKsfoxRdfZNu2beTPnz+5w7N3CPrBgwdq6f/zzz+rbilgdNTYu3cvkHTYRO537Nu3L72JMFZB7gOmZU+3Vq1a6uRjMplUuMlWmLdb27lzZ5IOedSoUXh4eNhlj3j9+vWcP38+yee6dOmiQmsAmzZtUnkBYHRHkgkptWrVsq2hyRAQEJDICc+ZMwd43Ig8jTxVDticR48eqVD+ihUrGD9+PAAvvfQSv/76q8O+24xgfj6yxkXtwoUL+fzzzwGYNGkSzZo1S5ezTQ550du5c2f+/fdfALskPB46dEgtkAD++usvIGmlqqyIbKpy9OhRhg0bxpgxY5I7VIegNRqNRqPJimTpFXBKxMbGqo1983aEAQEBKikBDO1YGV7JaLbs9evX1dVir169MmN2ovcFI3R66dIlwLh6TqpZtC2RV+hJrYatnUySUaQ2cMuWLVXIGYwQ3NKlSx1llqJdu3asWbNG3dcr4MwhM0/fffddWrdubfHZZnXMV8DWyIi+c+cODx8+BLCaRvHKlStVyLxixYrq87ZH0ltERISFLr+tV8BHjhwB4LvvvlMJf3Xq1Mnw+8lypR49elCtWrVEvQfMSPXDzLbNGHLmzKn2DLp06aKyn48dO4aPj49ymFu2bFHlIhntI9qoUSPOnDkDwG+//YanpycDBw7M7H9BhX0uXbpksQdsb8xDZAn3iuV9k8mkTiT2Ll2KiIhQ2YbmzhcyN5GSYt68eaxfvx4wQk0y9Jcd9qeeJMzLO+zZgCMr8uyzz1qjNy0AFy9eBKBfv36UK1cOgB9//NFu2eaOYNy4cYCRtSy1JFatWpXhc8fq1avV3zJbP8OkRS7LBjebcvHiReHq6ipcXV2FyWQSVatWFVWrVs3w+3Xo0EHkyJFD5MiRQ5hMJpEjRw7RsmVL0bJlywxpTF+7dk0MGjRItRST72symcSff/6ZYTvNsYams9SLljq48m97cuXKFTFx4sQk20v6+fmJmJgYq47n5uZmITPYvn170b59ezFu3Dhx5cqVJF8TFRUlmjdvbvG6OXPmiDlz5qR3eEdLSmaZ+Zw/f36RP39+9T3bi1GjRmV47jiqVWFaWbFihShSpIgoUqSIaNCggYiMjBSRkZF2teH27dvi9ddfV59P8eLFxZUrV5KdW9Zgw4YNYsOGDaJw4cLq3FG8eHEREBAgzp07l6YWpzdu3BA3btwQ3bp1s/htHj16NKWXaSlKjUaj0WiyJGnx0ja4Jcv+/fszdGUWExMjYmJixJ9//inc3d0tVkqZXQELIYSvr6/w9fVVzR8wawTRqFEj0ahRI9G7d2+xYMECsWDBAnHw4EFx4MABMXz4cDF8+HDRu3dvteJN+B4uLi6qUYM1MG+4YK0rcGx8VR8bGyt27NghduzYIerXry/c3d2Fu7u7qFixosV36eTkpFbitmhi8eOPPyYSZ5e30qVLi/3794v9+/eL6Ohoi8bn5sc5OTmpTjDpxNErWYeugG/duiVu3bol/Pz8VMTJzc1NnDp1ylpDJIv56lV2Q0rv6xP+XrBho4b0MnbsWJE/f37Rv39/0b9/f7uvfB8+fCgePnwo+vbtK0wmk3B2dhbOzs7iyJEjdrNhw4YNonbt2qJ27dpqjpcoUUKUKFFCrF69OtnV8JEjR8TLL78sXn75ZYtz0ZAhQ0RcXFxKQ6Y6d7JcElbVqlW5fPkyYEgUyr1X84bJSREYGAjA7t27LR53cXFRzaxHjhyZcYv/n0OHDrFq1SpOnjwJPFa8AmOfNOHfSSlhCWHUB8u64J49e1KqVKlM2yZJqHyVEZ1aeZw9JCzHjRvH7t27U/yO5R7sl19+ia+vr9XGTgrZ0HzhwoWJao4lnp6e6rs23xMCQ8da7rWlk+y6EZfpk8i9e/f44osvAJg9e7aaD+vXr1e19LbE/Pcuf9uyFC8pzPMjkkpelJKVjlSZO3funDr3HTx4kC+//FJ9xvaS+ARDt/rTTz8FDNW4ggULqrlu79p9mTDVr1+/RPkkMsHN1dXV4vEHDx5w9uxZdV+qePn4+KSWG6LLkDQajUajyYpkqRXwoUOH8PDwUCopqb6J2WozITKbeMaMGbz88ssZtTNN/PjjjwCcPn060Qpc0rNnT/V3w4YNbdJ0wZzUtG3BcmUMSa92zbHVVX1qWtCVK1dWY3t5eVl17JQ4ceIEU6ZMAYzs6NTmilxVDBgwQL0unTyVK+ATJ07QtWtXjh49qh6TykkvvfRS5ixLJ9bKBnZUxcC9e/eYNGkSYGjpy65iP/30k926xNWrV49q1aqxf/9+wFAFlCJKjRo1YtiwYUp72lHcu3cPHx8fbt68CRjRLlnWmtRv4K233gKgcePGqgdBGiojspcS1sOHD5k0aZL6UJJj5cqVhISEWDhg6WSbNWuGq6urKhPKnTu3Ne3OliTXDSk17NVi7ZdffqFHjx7qfsOGDWnTpo267+Xl5fA2az///DN79uxh4cKFgFGHnpAqVaoAhkPJIE+NA46KilLNGCZMmEBYWJhqpvHbb7+p79/e5THJSUqmBUeFnaVzGzBgAIsWLcLNzQ2A4cOH06lTJ4B0NSHILCaTyeJ7q127tgrbtm/f3m52pIerV68qByxbiUpKlizJZ599BqT7c9QhaI1Go9FosiJZagWssT3mV+c7d+60CEEnd5zmMefOnQMMpSapiHPx4kVcXV3Ztm0bkKmezk/0CvjGjRsqgjBlyhRCQkIAo2FKkyZNVAOLrEJKq2G52pXYa75s3LiRzz//XK0o3d3dVYKTTHaS4jGO0MDXWJC9QtAazVPOE+2ADx06pKQAixYtSlxcHAAzZ86kYMGCPP/887az8AlBCMH27dvVhcz8+fOpXr06YGzlVKtWzZHmaSzRDlijyUY80Q5Yo3nK0HvAGo1Go9FkRbQD1mg0Go3GAWgHrNFoNBqNA9AOWKPRaDQaB6AdsEaj0Wg0DkA7YI1Go9FoHIB2wBqNRqPROADtgDUajUajcQBOjjYgI+zbt4+TJ08q6TpnZ2eeffZZAIYNG8aLL77oSPM0Go3GLty4cYOIiAjA6Drk5eWlJCgrVapEfHw8YPRZf/nll+nVqxdg/yYXWZEZM2bg5+cHwAsvvKA6R3388cd262KVbZSwNm3apNpAnT9/nri4OIoUKWK8mRDcuHEDABcXFzZs2ECNGjWsaG72Y9++fYDRtWf8+PGsW7cuyeOEEClOxqJFiwJGt5AnmbCwMMCQ89u8eTPwuLsRGF226tatS4kSJWxpRnY9Kz6RSlh79+5VetX//PMPoaGhLFu2LNFxXl5eLF261K62SW3qnj17Kn3yHj164OXlRdWqVQGIj4/nv//+A+Cbb77h77//VvZ37NjRrvZmNf7991/q1q2r5FDhcXvbXLlysXr1at58883MDqOVsDQajUajyYpkmxD0gAEDuHv3LgBff/01VatWpW3btgDcuXOHihUrAnDlyhWOHj1q8xXwX3/9BcCpU6csHv/3338Bo9/p/Pnzk3xtlSpV1GoeoFOnTjz33HNWtU9+NrK38jPPPJPkcfHx8ck+BxAdHQ3AqlWr8PT0zLRd8jvs2bMnS5YsUY8XKVKE9957T91v2rQp8Pj/YUvOnz+vxgsODlaP7969W/09a9YsXF1dqV27NmCslHXzgMxx/fp1wPjMT506xdixYwEjlNqwYUMAPD09VW9veyF76C5btgx3d3cA1WNX9ootWbIk/v7+6rilS5eq19kDeb4oU6YMM2bMAIz+3Qn7n//vf/8D4IcffgAgNDTU5rbdv3+f/v378/vvvwMwdepUXF1d1fNt2rRJ8ZxjD+Li4ixWv+bExsbywQcfcOTIEQCbRr2yTQg6MjJSfWkFChSweO7GjRuULFkSMBzGX3/9Rb169axgZvLIBs3yx58ZTp8+zUsvvZTp9zGnWLFiwGMH/P333wPGBPz222/VcStXrkwyBL1161aL/1ubNm2s0i7u1q1bAFSuXDnFsHbevHkB6NatG35+fuTPnz/TYydFWFgY9erVU422+/btq55r2bKlutC6d+8eJ06cYOvWrYDR6s38byvx1ISgd+3axeDBgwHjotVkMqkQYOXKlTl58iRg7FW+++67LFiwwIrmJs+UKVOUXZMnT8bb2zvJ4/bu3Uvnzp0BCAkJITg4WDnprMT27dsB44LW09OT5cuXA5Ajh3WDn7dv32bSpEkATJo0iaioqGSP/fTTT5k+fbpVx08vQUFB1K1b1+IcJH9/8nz4zz//AKiL7gygQ9AajUaj0WRFsk0IumDBgsk+d+bMGRUq1STG39+fjz/+GDBCzuYhPfPVW2hoqFp5zJ07F0CFWZMLp6eXQoUKAbB//35u376tHr9x4wa//fabuv/TTz8BRuisYcOGarVhbX755ReCg4MJDAwEoHz58hbPV65c2eL+nTt3AOjSpQtvvfUWAGvWrFHJapqUGTNmDAAjR47ExcUFgIEDBzJs2DCVVAmPw9O1a9fm9OnTdrMvNDRUbY0kFVKWyVaff/65StBasmRJllr9ygTMzZs3M378eMCI2I0bN87qK989e/YA0KFDhzQnav7444/4+voCKZ/XbUmZMmVYsmRJstnOJUqUsHpUMimyjQNOCnkyHD16tAofFC9e3C5lSK+99hoAH3zwQZLPDxw4kDNnztC9e3eARCGZ3LlzK6ciS6hsRf78+VX4/plnnrFwulevXlUZ0t9//z3Hjh2zeK10MgnD/pnFzc0t0UmrcePG6m8ZEv7hhx/YunWrzRxw6dKlqV27tipBSA35XXXo0IGePXsCRh6AdsCpc+rUKeUQGjduzJQpUwCoWbNmomPl/ntERISFY7Y10qaE7N27F39/f5VF7OXlxd9//w2QZZxvXFwc4eHhNG/eHDDKkIYNGwbA0KFDrT7ejh07aNOmDWBs0ZiTO3duatWqBRgZ115eXgDUq1ePS5cu4aCtT0VkZCTDhg1L0g4hBF9//bV9Lg6EEI64WQV/f3/h7+8vTCaTui1ZssRab58pYmJihJ+fn8idO7fInTu3hY0mk0mMGzfOpuP//vvv4vfffxdz584VgYGByR7XunVr4eTklOStZ8+eIjIyUkRGRtrU1oSEh4eLChUqiAoVKoiCBQuK9evX23S8ixcvpvnYLVu2iC1btojq1asLjL1PsXPnTmuZ4qj5aJf53KtXL/X7P3nyZKLn7927J+7duyeGDx+uPtsOHTqk9e2tTnBwsPDy8hJeXl4CEO7u7mLPnj1iz549DrMpKeTn5uXlJYoXLy6mTp0qpk6davNxN27cqL4nQDg7OwtnZ2fRo0cPERQUZHHsrVu3xK1bt9SxN2/eFDdv3rS5jQmRdjRs2DDROVna1rdvXxEXF2eN4VKdO3oPWKPRaDQaB5BtQ9Bbtmxh0KBBgJG1Jvdr2rdv70izFNOmTUsx7JNwr9HavPPOOxb3Hz16BBhZ0bIkYdGiRZw5c8aiJECWb/3222+4uLhYvTwqJWSJxFtvvcWZM2cAaN68uTUK4lMkpfCz/KzOnDlDQECAEnwxD7kNHz6cb775hgYNGgCQM2dO2xmbjalUqZLKMK1UqZJ6/Pr166xatYqpU6cCxmcts547dOhgdztl5rO/v78qQ0opI9qRDBs2jPXr1wPG9tu+ffvsFhIvW7asmpv58+fn/fffBxKXDt66dYtWrVqp+97e3jbfdksOWUYmqxuSYuXKleTLl0/5FBlKtwXZpgwJHteQjhw5krlz56o94HLlyinFF7l3aE+kXT169GDTpk0APHjwgNjY2GRfkzdvXnWinjVrls32OCWrV68GUHsxkoR1wCtWrADsU39rzqlTp1Tp2O3bt5Xj37Ztm0NVzaRzvnTpksXjrq6uKulEziG5h+3p6WlR550OnugypOvXr6uSjosXL6pEq0aNGnHmzBlatGgBwIIFC+y67wuohKr69eurvwF1kS8dsaRu3boO2/sNCgqiXbt2AJw9e1blIvj6+jrMsSWFzHvp3r07ixcvVo/7+fnh5GSs/Y4ePapydry8vChXrpzNzuEbN25UFwxJlV7KeSyfk+fnwYMHM27cuIwMqcuQNBqNRqPJimSrFbBUJqlXrx5RUVHqimXXrl1KOccexMTEcPnyZcAQbpArYJkVmV4KFSrEzJkzgaRLH6yBDPlJ3VhJwhWwzJD+/vvv7aoXe/bsWV599VXACO9K4Y1Vq1bRrFkzu9mRELnSiI2NpXz58mqVW7duXSIjIwEICAggMDDQQiyiXLlyAGzYsCHNGdY84StgQK0khg0bxo8//ghAnz59MJlMqnGAI9i7dy+AUrdKSEhIiBJmkMhVsZeXF3Xr1qVu3bq2NRJDaKhy5cpcuHABgI8++kit0l1dXfnqq69o0qQJYGxzydWkvaNIN2/e5KOPPgKM+ZFWRo8erTK3rb2Vs3DhQrp27QqkbQVszpYtW4DHCn1pJNX5nK0csOTAgQN4e3urOH7t2rVVbL9OnTo234NLj9SllMh89913LR6PiYlRNZHw+Me2YsUKWrdubSVLHyPF219//XX12A8//EDv3r2TlIUrWrQo5cqVU7W59gi3HT58GDBOgtKZFS5cmK5duyqVHRm6yorIMPW4ceOUc/nggw/SU0P9xDvgpOjQoQOrV69WJ8CNGzeqcHRWRu4J792718I5Dxo0KNlypsxy//79RKpw8r67uzuFChWyaBghHXD16tV599136d+/P2B9JSxz7ty5Q8uWLdVFjTnOzs507txZXdybh5uXL1/OnDlzlMKctTsSmTtgiZTuNHesp06dIigoKMn3OH78OC+//HJah3wyHTAY+4SyZrVbt25cvHgRMBydj4+PTWuBk3PAVapUUeMOHDiQypUrqx9YwpqyR48e8c033wCofwH69+/PtGnTbGV6igwdOlStAGJiYgDUZH777bftast3330HoERDpJCIFOjIysTGxio7+/fvr1YAabiweiod8IMHD+jatSurVq0CjI5mn376KQAjRozIvHV2QNYJgzFn5KrU2o5YCMG5c+cs9lQl77//PqVLl1a5MfBYKGPfvn3MmDFD5YLYMmJ45coVqlSpomRwnZyc+PzzzwEsZHCTonbt2kpU6ejRo1a1Kzo6Wuky3L17l44dO6pcFykQBMbv8fr16+oCwLxuefr06eq3mQb0HrBGo9FoNFmStBQL2+BmVaKjo0WnTp1Ep06dhMlkEmXKlBFBQUGJisGtxe3bt8U777wj3nnnHeHq6iqmTJkipkyZIs6dO5eu95k4caKYOHGiRTH4Cy+8IC5evJgucQhr4uLiIlxcXJQYh6urq3B1dXWILUIIMX36dJErVy5VJL9o0SKH2ZIe4uPjRXx8vChbtqzo3bu36N27d1pe5mhBDYfOZ19fX+Hr6yvy58+vvm9/f39rvb3dWLJkibI/qwgDLViwQM0fe8yhQ4cOqXNyeHh4ml/XoUMHUahQIVGoUCEbWpc6Fy9eFG5ubsLNzc1CpGP69OnpeZtU507W3VBLB7ly5VJ7rMuWLePSpUtqH0EmAliTZ599VrXayihRUVHKRnOCgoJUUpfG6JwSHh6On58fAP/995/SkLZnjXJ6kXts7du3548//gCMekjzUJfGEhluzpEjh/rbz8+PFi1aWNQNZ3U6depk87LCtCK7IfXv35+KFSsmKkO0FTVq1LBoN5pWQkJCePjwIQAnTpxIz36r1YiLi6Nz5852ad2oQ9AajUaj0TiAJ2IFnN2IiIigV69e/Pnnn+oxmYk8duxYKlSo4BC7QkNDk21S7Ui++OILpZI0duxYtQKWiVpZmQIFCqhOSyEhIXoFnAaGDRvGgwcPACOj/IMPPuDAgQMOtirt2CoDOr1s375dlfSULl2ajRs3JlnxkNWQlQ72jnDJqpqvv/462d9bOkoK00SWd8CyLV6XLl3IkydPssfJGlzx/9lq8t+shFSZmj59Ort27bJ4TirYfPnll3a3S9K/f3+LDErAQkLOURQqVEhlbW7evJmIiAgHW5R2fvvtN+V0s5JKUVZHqjv9/PPPnD59WrUklGV9tkQ60PTW9spWhYMHD1Zle/aoDTbnwoULzJ49GzDa/tWvX1/97erqaldb0suhQ4c4duyY2k60VumjXOiMGTMmRQe6cOHCZJ+TClrmZZzWIEs74MDAQLWHmzNnTqU1mpBbt26pH53JZMLZ2dmuIhIpIYUvVq9erfZ8EzpfNzc3VYKR1RgyZIijTQCM/pyOJCYmhpiYmEQ1mEnx6NEjJkyYABh7+o0aNQKsf/X8JFO6dGnAmBsHDx5UpXlSsMaWyGhLevZL9+7dq0ptALX/aY/6eSmJ6ufnx2+//aZWuT4+PqpkxpZ1v5lFSlZ+/PHHCCH48MMPrfr+0gH//fffapWblNiGJOFzRYsWVSVmsm7YWmTdb0Wj0Wg0mieYLL0Cfumll+jRowdghKSk9F+lSpVo1qyZ6kzz3XffWWQODxkyxK77B3K/6uDBg0qEX2by3b9/H4CwsDB1fKFChahataq6P2nSpCSbkqcXGUKZNGkSxYsXB1CKUvIKOF++fBaflXlB/pUrV9Tfzs7OjBkzRq1EHI25uo8jMkyXLl2Kr68vv/76K2AoriXH0aNHVSesHDlyZJkoQnZCNmqIiIjAZDLZJfQskc0Y0rp69fb2xt/fXx0fHBxs9ZWvlL6Vq8Xly5erx2UDmEuXLrF27VrVlSsrq8aZ07dvX8CQGq5YsaKSe7UW5ufa9CDlZJcsWWK7vJy01CrZ4JZmYmJiRExMjJg2bZqoVKmSqFSpknB2dhb169cXtWvXFrVr17aoo3V1dRWHDh1KzxDp5ty5c6Jr167q1q5dO9GuXbtEDZ7Nbzly5BB58uQRefLkEUuXLrWpfePGjVNjyXpeWVs3YsQI9ZiTk5MwmUwW9+WtV69eNrUxrcTFxYn+/furz7FMmTIiODhYBAcH29WO8ePHC5PJpJqOt2nTRsyZM0fMmTNHNUQfP368GD9+vChcuLDN6gaz6M3qDB8+XAwfPlyYTCZRs2ZNWwyRLKRQwyt/e4MGDVJ1ooAYNGiQ1X+X27ZtE9u2bROtW7cWhQsXtvhdyVvZsmXFhx9+KD788ENx+PBhq41tbU6dOiVOnTolFi1aJB49eiSioqJEVFSU8PX1VXMqZ86cYtu2bVYfOzY2VsTGxoru3burzy2pc7R8rkCBAmLgwIHi7t274u7du5kZOtW5o0PQGo1Go9E4gGypBT1jxgyWLVumkplMJpPKTps5cyZly5bNvIUp4O7uzv79+9N07AsvvAAYGtW+vr62NMuCYsWKASg91uRI2A2paNGigJF97khBfKlFPXjwYL7//nsVTgsICFAZifZmzJgxzJgxA3ic+JIcUtx99erVFChQIK1DPJVa0BLZwOL06dMqEcpkMrF8+XI8PT2tMUSakJnLYWFhSou8ZMmS+Pv7WzRdkN2Qli5dapNkK3nuCAoKUue0du3aUa9ePRVWff7553n++eetPra16dWrF2BouTdo0EBtg5nrPU+cONEikc3ahIeHM2vWLADVbEGeZ5YuXcp7770HGGVI5cuXt8aQT24zBkeSnAMuXbq0Rap/u3bt6NKlC2D/DFhZx7ZmzRqlIpUU5g7422+/pXnz5oDRPcWRfPLJJwBqwsisYltO0LQg9wd//vlnlbl+/PhxAN566y3AyF0YNWoUkO5axqfWAY8ZM4aRI0cChtPNmzcvYNQEy1pWeyG/Y39/f4v2hF5eXhYtCO2R4fykMH36dAA++2j9qmYAACAASURBVOyzRM/JPB9/f/80VRlkI3QzBo1Go9FosiJ6BZwBZsyYoa7k6tWrp1pc1a5dm1deecWRpj0RDBgwQKlctWvXjhEjRqgs8axcz2gFntoV8KpVq1TLy7fffluJMdgz9KyxPY0aNWL37t1qi8zb25t+/foBRoXGE4YOQWs02Yin1gFrNE8gOgSt0Wg0Gk1WRDtgjUaj0WgcgHbAGo1Go9E4AO2ANRqNRqNxANoBazQajUbjALQD1mg0Go3GAWgHrNFoNBqNA8ge/aqSQTa7Dw0NZeXKlerx0NBQJRP47LPPMmLECMAQeMiVK5fV7ZC6pnXr1qVKlSoAjB07VrWz0mRP4uPjCQgIAAxxiGrVqtGqVSv1vGyb1qBBgydRRMDuyJZ7Q4YMUXMqKioKFxcXChUqBMA333yTHm3tVImMjKR169b8/fffST4v9ZgvX77MjBkz+Pjjj602trUYM2YMYMijhoeHExsbm+RxefLk4cKFCwAWkrlPE7KdY6VKlWjQoAHvvPMOYMzhZ5991u726BWwRqPRaDQOINsqYW3ZskWJ3yd3xZeQCRMm2ETM/48//gAM2URJ2bJl+eyzz+jfv7/Vx3sauHHjBgCLFi0iICCALVu2qOe2b98OgIeHh03GPn36NAAjR45kxYoVyR4n507+/PkZPHgwX331FWCsNDLIU6mEdeLECYYPH85ff/0FQK5cuSyaWFy+fJk7d+4AxnfyzTffZGY4C7744gtOnTpF27ZtAejYsSN79uwBjI45Fy9eBODhw4fMmjWLa9euAVCkSBGr2ZAZgoODmT9/PmBE4FxdXdXcMefQoUN4e3urjmwyKmhLTCbj52zuY+Rj5tjTBz18+BCA+vXrc/jwYfW4q6uriiRYMcrx5EpRLly4kA8++CDJ53LlyqW0ZBcsWEB8fDxgdKa5detWZodOhHzPd999V/34//33XwDGjx8POL6LT1I8evQo1baKlStXBrBreGbPnj0MHjwYgH379iV6PmfOnAD06dOHadOmWX38zp07A7Bs2TKLx5977jnat2+vbAwMDAQen1SWLl0KGCfxDPJUOeCtW7cC8P777xMVFcXcuXMB4+Qo22ICbN68WTnITz75hMmTJ2fWXsWIESPImTOn6l6VHA8ePKBhw4aqTd3ixYutZoM9WL16NZ6envz6668AdO3a1WZjJeVk04I9fVFcXBzz5s3j999/B2Dnzp08evQIgPXr11ur5amWotRoNBqNJiuSbZOw3n//feLi4gCIjo5Wj+fLl4/3339fJWHJ8AyQ7Io5s8gEkQ0bNqjkkQ8//JCAgACGDx8OGKvNL7/80ibjpwXZePrkyZMqYW3VqlWcOHEixde9/vrrgHFV6ORku5/LoUOHWLhwIWB0m5LfbVLILQf5uVsb2YTd3d2dvXv3AtCpUyfKlCnDa6+9po5L2LP4ypUrNrHnSUXO0ejoaNatW0e9evWSPG7z5s0qeaZkyZJWtWHIkCHcvn071eOcnZ1p0aIFR44cser49mLs2LHkyZOHOnXq2OT9M7rqdRROTk706NFD9SJevHgxffv2BaBfv36cO3fOLp3Xsm0IOjVkW8D//vtPPebv78+AAQNsPTRg7DVs3bpVhc5y5crFn3/+CTzOnrUHFy5cYNasWaxduxZ4vL8JUKtWLfLnz0/u3LkBIywVGRkJoFqEyWzJoKAgdZy1iYmJoVmzZklmolarVo3BgwdTvHhxAIYPH67C5suWLVMt7ByBvPBr2LAhBw8epHr16oBxMZFBstdZ7DEZms/Hjx8HoESJEhQuXDjJYz755BN++eUXtaX0448/2vRCMCFy79nPzw8/Pz9rbDPYjdu3b9OrVy8Ali9fzsKFC1XWr7XJjAN2kA+y4NGjR2r+Hj9+nLi4OJ555pnMvq0OQWs0Go1GkxXJtiHohMiw5M2bNxkzZoxKkIHHYVS5qrMHefLkoXXr1urqLiYmRoWBbYW8Wv/pp5/44YcfAOPziIyMpGzZsgAMHTqUjz76CAA3NzeLVW1MTAwTJkxQ93PkyMEvv/wCYLPVLxgJLuar31y5cuHv7w9At27dyJMnjwpJe3h4WEQ1HMmpU6cAOHjwIICu+04nMkqVkNjYWNasWQMYSZSAWrnZc/ULqEzZKVOm8Mknn2SLla9MCm3VqpVKBrXl6je7cvPmTTZv3gzAzJkzVUSmX79+dgk/QzZ3wP/88w9ghKWkKIcsZZBUrlyZn3/+GbDv5A0MDMTf31+FZvLmzWtVAYGEbN26lW7dugGGEInE09OTDz74QJVsyQxic3bs2AEYhfy//fabetzX19da2YApEhwcTKFChejZsydgnDgaNWqkng8PD2fTpk0ALFmyhEGDBgE4NPwMj7OeJZ06dXKQJU8W3bt3V7/DcuXK8e2336qLaHsgM+9nz56tvuP4+Hj27dunsp87duxo94uBtHDr1i0lFnPlyhV27twJGCVKGqOsEYw8j+jo6CT3/+vXr28/g4QQjrhlioiICDF69GiRM2dOkTNnTmEymZK9rV27NrPDpZk7d+6IXr16iV69eonnnntO5MiRQ9nh6+trkzFXrVolVq1aJVxcXESRIkVEkSJFRKdOnUR4eLgIDw8XcXFxyb42PDxcjB8/Xjg5OQknJycBiPLly4vy5cuLffv2ifj4eJvYnJDIyEhx5coVdT82Nlbcv39f3L9/XwwZMkQULVrU4juV/zdH8uuvv4qCBQuKggULCpPJJAoWLCgOHDggDhw4kJm3ddR8dMh8joiIEBERESIgIED06dNHvPDCC+KFF14QGHvKAhC7d+/O6NtniAsXLoiXXnpJvPTSS6JChQqiSZMmokmTJmLt2rWie/fuyq5+/fqJ6OhoER0dbVf7UuLPP/8U7u7u4s033xRvvvmmOH36tN3GNv/OMnuzJXPmzBFz5sxJNGbx4sUt7rdo0UJ4e3sLb29vcePGjYwOl+rc0XvAGo1Go9E4gGyVBS0LpadOnZpmYYs7d+6QP3/+jAyXbubMmaOyDiXy8+3Tpw8jR44EUBm91kCWZVy9elUpRDVo0CDZ44OCgujTpw8Ae/fuVfvGEhn6rVChAs2bN1dqUy4uLlazOSkiIyM5evQoALt372b9+vXA420Gc+bNmwfYrqwsOebPn8+2bdsAY09N/h5NJhNFixZl6tSpAJnZa3uis6Bv3LjBrl27AFixYoX6LKUGdFKUKlWKF198Uc2dJk2aZNbWTCEz8GfNmqXmto+PD6VKlbLpuLI6IWEZ1OnTp5Va244dO5g2bZrK8XB2drapTWCb8iNb+iQpyhQeHm7xeMGCBQkLCwOMypmBAweq+7Vq1VICJhUqVEjPcE+WEpbcj+nSpUui56RyTokSJSx+pMeOHePll1/OyHDpJjY2ltmzZwMQEhLCgQMH1P6qyWSiWrVqAPz5558WSj+ZQSozdenSJcnPJSEdOnRQ9ZdpQTYZaNu2rVIgsuYFBBglW0OHDuW7775L8nknJye1v/r777/j5uYGGJKUMrnM1tSrV499+/ZZnBzk3/IkJMsWRowYkaqyUjI8kQ5Y1po3b96cq1evJnlM165dVQ4DGGUzYDQ6WbhwoVJi8/PzU/WajqZFixaAke8xceJEmyZoSQ2BSZMmIYRI0vH973//Y/jw4Xh5eQH2kcu0Zf2vg3wTYJyTZGJot27d1MJkwYIF6SlP0mVIGo1Go9FkRZ6IFXDnzp0ZN24cYGieDh48mJdeegkwwglWKKjOMDKU2rFjR6Xm4+Xlxe+//+4Qu65evWrRxMDd3V39XbJkSXVVD+Dt7c2BAwfUfSkgIlf11sLPz49hw4ap+y4uLjRs2BCAN998k1atWqmrYQ8PD0JCQgAjVP3qq69a1ZbkqFOnTiLdbBkdaNCgAdu2bbNoCiJXwCNHjrTqFXMWJcX5vHr1asDIyJdayuXKlVOa2++9916KGcU7duxQGfLnzp1j6NChAGrOO5pPP/2U77//nt27dwMpbwFlFFkic/r0acaMGYOPjw9glEldv34dMPTJL126pObK1KlT1TaNrctqslsoOj388ccftGnTBjDOOen4fp+sELS0NTAwkGPHjqnShLx586ofaJMmTbh3756qXzUPazmSwYMHqz1CMPa9bL2vmhxyHwRI0TnEx8crRzJ27Fj1uLV/M5cuXeLTTz/l/PnzgHGB0r17dwDKlCljceyRI0fUybhWrVr4+fnZpVHE2bNnmThxogqhNm/e3KLT1ZYtW1SY0HwL5NChQ0phJw08kQ5Y7pWHh4erLkfpLcmTXYnq16+vLs6WLFmSbkNtwaNHjxgwYICqKd20aZPV94TlxfugQYPw9PTkjTfeSPZY2dTi448/ZsiQIYDRM9iRTtj8nJEeZ50VnLAQwqIsUl5opYEnywGnhGwl9fXXXwPG3i9gt/3f1Lhw4YJabd64ccOhDjg9SH1m8+4ptvjNPHr0yGJPNaWThWypNmrUKAIDA7OMAIbUHZcXD6AdsLWpUaOGqnMPDQ21qUBMepHfc7Vq1fjpp58AQ1TGGgQEBADw3XffqS5SySEFf7799lv8/PwAI3q1ceNGq9iSGkm1IUzt2OTICg4YHke0pk2bphLi0oDeA9ZoNBqNJiuS9aRcMsCQIUOYMWOGuv/hhx9mmVWRpGzZstSsWRMwurvMnz+fL774wsFWpczDhw/5448/1H3zvWNrk9bw2F9//aW2F1577TVKlChhM5vSy4ULFxxtQrZCdppat26dimClhYiICOBxaNuanD59mooVK2botdOnTweMioFatWoBxv6wNZDnt7TsP8pV96hRo7j0f+ydd1gU19fHvxgFCyoYC8RuYi9BYyFWMNHYW6wRTVQsv4g9GmtUbFiwoMbYC8auoBjBil0Q7L3EAio2sIBIv+8f897DLr3s7qzkfJ5nH9nd2Z3jzM49c/rjxwCU0r2JEycaJG6uK6vVWKzfjx8/kidQ16iugGNjY6kdWGbS5iMjIzFt2jQASrKB7BVcqVIlrF692ijbxGkiFxFj5cOHDxg4cCDF2YoVK4YlS5aoLJWS1CYXlYkTJyJfvnwqS5SI5qQpJm3i4uKotjKzbmTp6k2prWp2CQwMzLIClrHpvn37Uhy2Z8+eOikHkq12HRwcMvW5VatWAVDc0gsXLqSkrKz+H7PCpzaqMClbt26lm2s5qlRXsAuaYRiGYVRAdTNx2bJldLd4+vTpNDNaZZnHrl27sGjRIppCAyhF6ACwZ88eo7R+3dzcaKAAoJT4GCOyefu4ceNw/vx5mge8bt061KpVS2f7efToUbIM54ygmWG8c+dOyohWmxMnTlAnMktLSyxfvhwAT0hKDXd3dzpesjtWWsjmMXfu3KGSEH1d5zt37gQAamiRFeQ0ttDQUJ1YwDLj3t/fHz///HOGPyeP0ebNm/H333+TRbxw4cJsy5QeWbV8jcX1LOe3Dx06lNZB2UVQV6iuqby8vCj+l9YJ8/T0hLOzM4Dk7disrKzwzz//AFCmHxmaDx8+AAAWLVpEg8NlhybpOlq6dKnW/8+Y3DJhYWEAlFGFMr4aFxeH9u3bU/lRaqPjMrsfOV3J2dk5UwpYZrf7+vpSCYbm5CZ9cPLkSTx//pyely9fnmJ7QGJt5tKlS+Hh4YHQ0FAAiisyI13J/svs3r2bOsOlVw3w7Nkz+l1+/PgRzZs316ts0s0bHx+fqfMos2O3bduGjh07Ash068JU6dChAwCgbdu22LhxY6aUMJAY8sqfP79O5EkLY1rbkiJ7SaQ3uez69et0jCtXrkwxYF2dT4nqCtjX15dO2OjRo7XqA+Pj4/HXX38BUBRC0jsjWcg/depUg8Y0kiIbMty7d49KjRwcHPDo0SOaJxoUFETbOzo6wsLCwvCCJsHX1xf79u2j8gTNGOa0adMwYcIEnZVRAIo1IBt7aDatSIs7d+5g+fLl1OLTwsKCypA+//xzncmmyc2bNwEoi528uQKAQoUKaSkL2QBB5jBIeaR8TOo8ffqUWlT27NkTY8eO1Wqq8vHjRwBKra+Liwvu3LkDAGjXrh0cHR31JlfHjh3Jeu3fvz/N0x0wYEC6a4xs1RoeHk71t7pCelJGjhyJ8ePHk9HSokULss5SQv6WW7VqBSsrK70eO12gb+tXtjE9ePAgHB0dUbt2bdqvbH+6e/duHDx4kGrWJ0yYoLdyVo4BMwzDMIwKqN6Iw8nJCX/++WeGPvTll18CULrhdO3aldom6iMbMiusXLmSyinktA3N5hLff/89AGXwvRwooA9CQkIwZswYAEp7uokTJ9Jkj5iYGKxduxaAMrw7d+7cKF++PAAle1NO8rG2ttap9Sv3Ld3HZ8+eJff2iBEjtPYVGxtL1tGIESNw+vRpeq9w4cJkoehqoEVSZKOHJk2aUMZ1SiQdxiBzGTLrHtTAeH13aZPpRcTb25vaj16+fBmmpqYUkhBCkIfk0aNHKFq0KGUYu7i4UJtZfSFdyW5ubpg3bx4A5bc2evRoOudFixZFdHQ0/b1+/XpqOztt2jSdW8CabN68GcOHD6fn8tg0bNgQDRo0QGRkJAAlV0aGaSwsLHDkyBGdhJLSI7MuaEPqINnQRA6xSQ0LCwt4e3sD0G7Xm0mMvxNWTEwMTcGRPX5lwsWTJ09IaU2ePBnVq1cHoD/Xoy6Q8emtW7dixYoV5PIoWrQoRowYAUB33XFSY86cOVq9lZNiaWkJQHHnjRw5kuqTDcHFixcBKPWMsr1ejRo1yBUEKAksMnYuk1jkBdO4cWODjSG8d+8edbeSnD17FoCy2MlpKS1btsTw4cOpnCYbyUH/GQUMAC9fvgSghEJ8fHyoFempU6fI/ffjjz9izpw5qnWNk7/DGzduYPfu3Vo3Xfv27QMAGukp44v6nIokkcdu8eLFFDoKCQmBn5+flgKUY1snTpxo0LBXRpWwofWPbMN77do1rFixghIAra2tKVnujz/+gJWVlS6S57gTFsMwDMMYI6pbwIzuCQ8Pp4zxQ4cOoXz58ihVqhQAZSiEnOdriIHdSZHuvfbt25MFmRaWlpb4559/suMG+pT4T1nAzH+DpNawsZQZGQDjd0EzDEOwAmaYnAO7oBmGYRjGGGEFzDAMwzAqwAqYYRiGYVSAFTDDMAzDqAArYIZhGIZRAVbADMMwDKMCrIAZhmEYRgVYATMMwzCMCrACZhiG+UQ5evQo8uXLh3z58qFly5YYNGgQQkNDaTY1Y9x8Mp2wLly4QI2z3dzctKbUCCEwdepUAECVKlVUG4YeGxtLP/xNmzbB29sbx48fBwCUKFGC5u7a2NgYVK7bt2/TPN0NGzZQO0gTExM4ODigXbt2AIA2bdrA3NzcoLJJIiMjaQrRunXrcO/ePQDAnj17ACgzOQFg3Lhxem8qL+eCurm54dSpUwCUofFz587V2k7OaG3cuLGuds2dsJhM8fvvv+PWrVsAgEuXLuHJkyeoVasWAGXi1BdffKGmeACU9XnJkiUAgFmzZqFy5copTmXKly8fhg4dSlPvcgA5pxXlokWLaLJHsi8TgvqNmpqa4uuvv4afn1/2JMwCLi4umDRpUjLZAEXZyYth6NChGDNmjEHGKO7cuRPjxo1DUFBQijJp8s0332DOnDkAgO+++07vsknc3d0xf/58GkGYFubm5qQg5WhDXVOhQgUAynQuOT3ls88+S7adnJZib2+PLVu26GLXOVIBy6lXT548wbp16wAoI/Xk9DMAqFevHv744w8AynnV98SwrPDo0SO6SQQSbw7fvXsHAHTTeOfOHVy5cgUAYGVlZTD5Xr16hXHjxmHDhg0AgNatW9OIREMTExODhQsXAlBGAGZ0PbawsMC1a9cAgPrXf8JwK0qGYRiGMUY+GQt427Zt6NevHwDl7krryzQsYECxguV82S1bttCgb33j6+uLHj16AAA6d+6Mrl270nBsJycnPHv2jLYNCQkxyIzTZ8+eYfr06fj6668BAFeuXCELOCQkJNkdcq9evQAoFoq+kdbQkCFDEBcXl+HPyVmxW7ZsQevWrXUul3SXbdq0CWXLlgUAeHl5JdtOWseWlpbYs2cPmjVrlt1d5ygLOCEhgbwbAHDz5s0MfVmzZs3g6+urO+mySHh4OAICAgAoM8q3bNlC13NUVBTN1W7VqhVKlixJ10zu3Llp7nWxYsUMKrO7uzvNy7ayssL58+cBAKVLlzaYDGvXrsXEiRNpZrEmhQsXRpcuXVCjRo1k702fPh3v37/H77//DkDxKOqT+Ph4eHp6AgAWLFhAVnq5cuWwfPlytGnTJru7yDkuaACkRJK6KpMqYE3q1KmDI0eOAEhcuPXJw4cPASg//nz58tHrSd3TLi4uGDt2rN7lSYv4+HhER0ejRIkSAJQ4rCEVsFRumq5IQHGFay5cDx8+xJ07d5J93t7eHkePHtWbfKGhoTAzM6O/k1K+fHkAint6ypQp5ELNBjlKAQcFBWnd/FpZWaFq1aoAgD59+mhtO336dMrrMDc3pyH3hsLf3x8AsHDhQkRHRwNQYqoydGNtbY1ff/2V8iWCgoLQvHlzkvf333/Hjh07AChKUId5AZni/PnzaNq0KQCgYMGCpIDlb1Xf+waAdu3a4dWrV1rvyRtlV1dX+g1IpGFSvXp1vH37FqNHj6Zt9cWTJ08wbtw4CiNUqlQJDRo0AKCMcO3YsSPc3Nyyuxt2QTMMwzCMMZJbbQEyw86dOwEgmdv05MmT2Lt3b4qfadq0qUEsX0lqd5pjxozBoUOHAAAnTpyAt7e36hbwZ599hoiICHKlGhoZUnB2dgYAsi42b96MQoUK0XYHDhxA+/btARh2mPfnn39Of6uVHf4p89dffyFPnjwYP348AGDgwIGpJtY0atSIsnejoqLg7e0NAHoJMWgSGRmJAQMGwMPDA4CSBCRdyy1btsSPP/5I8hUsWJA+Z2NjgwcPHgBQrPlbt26RN0Ym8Rma+Ph4bN68mSz4VatWGcTylciQWnh4uNbrhQoVwuzZswEgmfX75s0b/PDDDwBA1Rn6RFrmLVu2RHx8PM6cOQNA8brJMJgMXxqCT0oBV6pUSetfyciRI1GmTBkA0MpSBAy7YKeEVG6LFi2ikiQA5GZRk+fPn6Njx450wQLJj60+kVntv/zyCy5dukRZzQUKFNDark2bNhg+fDiAxPisMSB/W2rdwBg7uXPnxsyZMzN0o3nw4EGtjPNq1arpWzwAwMWLF+Hp6YmJEycCAAYMGICSJUum+7nZs2dj5syZAIDevXvj6NGjGfqcrnnz5g1u374NAJgzZw68vLxQvXp1AKBYsKGQ4QZ3d3f06dOHyvS2bNlCZUfBwcGU5QwAx48f1wop1q5dm256dE1oaCiGDRsGQAlHenh4aGWpy1DljRs3qKxV37ALmmEYhmFU4JOygDU5d+4cWbtjxozBixcvACSvbb1//z7OnTsHAPj222/1Lpd0S0k3zMGDBwEojSSkbEWKFEHDhg31LktqSIt3zZo1CAwMpNcHDx5MDS8MgXTrmpubp5mpHh8fj9WrVxtIqozh4uJC5zOlGmFGcTlnJPv2yZMn+OOPP8gFmDdvXkrQ0zeNGzfGx48fM7TtoUOHyOoNCQnBggULAAC//vqr3uRLyrFjx/Dy5UtypS5fvlwrQbFVq1ZYtWqVweRJia5duyI8PBwzZswAoFjmZ8+eBaCsi2FhYSl+rkSJEti0aVOKGdK64OTJk5Qot3LlymQ12uvXrwcA1K9fn9ziekcIocYjW1y9elUUK1ZM5MqVS+TKlUuYmJjQ30kfJiYmonjx4qJ48eJi0KBB2d11mhw9elQUK1YsmWxJ5Vu6dKle5UiL27dvi5o1a4qaNWuSPObm5sLc3FxcuHBBNbni4uLEq1evxKtXr7Ref/XqlZg+fTodR81Hhw4dDC7nw4cPxcOHD0Xt2rVJjty5c4vmzZuLN2/eiDdv3mTn69W6HlW5npcsWSKWLFkiypYtq3Ve+/btm9Wv1DlhYWEiLCxMODk5CTMzM9GoUSPRqFEj8fbtW4PKcenSJXHp0iVhamoqoGSdp/iwsbERBw8eFAcPHhRhYWEiNjZWxMbGGkTGqKgoERUVJcaPHy8KFCiQppwpPZ4+fapX+R48eCCWLl0qli5dKqKjo7Xe27FjB8mxcOFCXe0y3WvnkypDkpbsH3/8gWPHjiV+WRplSJrvFS1alJK1bG1tsyJCmqTXCUtiYWEBT09PNGnSROcypIYsKxoyZAjVMiY9ZtWrV6fyiUWLFlEJjr6Ji4uDg4MDeQs6duxI7+3du5c6DUmkXIcPHzZYuceTJ0/QtGlT6ur06tWrZF2yZKezgQMHYvLkyVnZTY4qQ0qJ58+fAwB++uknup6lR2bIkCEAgD///FPX8mWJsWPHUjJYWFgY1q5dq/eksJRISEhA165dAYCSxWSeRFJr8caNG4iIiKDnsn1q37599d6VS7baTe8YaXY5i4uLQ0JCAgAl2dLQx/fNmzcAlNpzWTbq6+uL/Pnz6+LruQyJYRiGYYyRT8oClmVISYctZNQCBgAHBwcAwMaNG7MiQprExsaS5SPjQylZwIByByvLFurVq6dzWZIiM1EXLlxIJT6yDEhaHLGxsbR9jx49dNXfOF3mz59P3W8ygixbyqKVmSUePXqEihUrar2WVp9ozWOZCXKkBSzLSxYsWIAVK1YASLQ8JGvXrqU8gNu3b+N///ufHsRMn+joaIwYMQKA0gmtW7duAIBly5ZplSHJzGNJQEAAWfItWrTQaQw7ISGBuonduHEDderUwffffw8guQV8/fp1ahozZ84c6siVP39+jB8/nrwM+kCuZ1I2ebyqVauGgQMH0nb9+vVDrlyK7efj40NWb968eXH69Gl88803epNR8u7dO/j4+GDevHkAlKYrefPmBaCUmHXt2hUdOnQAkDh0JQvkrE5YkiVLluDmzZuUmFO7ThPUFQAAIABJREFUdm3Y2dkBAIYPH47ChQtTAoDmFCUgsSWb5jQlQyGV8qRJkxAbG0up7oZKeU8N6ZJu0qQJLl26BMCw3Yhq165NzeszgrwxMOTUq9evX6NFixZacsqpLTKUIIdERERE4OeffwaQmNiRQXKcAo6IiECLFi0AJHabSok8efLQTWp0dLSWsgMSG/M7ODhQLWnnzp2zJ7UGcj3o1asXucZ37dpFN10BAQEIDAykEhpZPwooNaWFChWi81+oUCHUrVsXgOJq7927NwDQAm8o4uLisGbNGgDA+PHjYWlpSS0+9dGeV7YIvnr1KoBEBVy5cuVUP/Po0SOtWuVdu3bprQwJSBycMWTIEGzfvp1et7GxoRDSkydPcPXqVQp1rVixAr/88ktWdscuaIZhGIYxRj5JCxhQ3H8yocPc3DzVblf79++n/saRkZHUsEP2bFaDiRMnYu7cudQ5JiQkRDVZNNm6dSu56HPnzo39+/eT9aJPQkJCMtXEQDZNkCUhhuLRo0daYx1lD215hy97yV68eJFGFfr4+FAP8wyQ4yzgPXv24KeffgKADI8YTEhIIBcloFhyqZUKyfORnWED4eHh5MoNCgqiZjRCCBoxCCjnVzYIadSoESVGJV17Xrx4gd27dwNQwiTSGt61a5dWhzdDsmTJEowcORKdOnUCAOzevVvrGKvF06dPUaVKFQCKt6RRo0aUYKuPkZTSJS/PyYABAwAoXdtkKCk+Ph5XrlyhUqQOHTpg7dq1Wdld+tdzRlKl9fAwGE+fPhVWVlbCyspK5MqVSzRr1kw0a9bMkCIkY9OmTSJXrlwib968Im/evOLIkSOqyiM5d+6cVrnUmjVrDLLfhIQE8fz5c3oEBgaK7du3i+3bt4tRo0YJc3NzrTIVU1NTYWpqKubNm2cQ+TKKr6+v8PX1Fblz5yZZT5w4kZmvULucSC/Xc0BAgAgICMjMcdDi5cuXws3NTbi5uYn69evT+TcxMRE2NjbCxsZGhIaGZvn7//rrL61yGAsLC2FhYSGqV68u3N3dhbu7u7h9+7aIi4vL9Hdv3LiRvvfMmTNZljG7REdHC3t7e5IlJiZGNVmS0rp1a9G6dWuS7d69e+LevXt62ZcsFRw0aJA4dOhQmtvOnz9fzJ8/XxQuXFgEBweL4ODgzO4u3WvH6BpxREZGak2esbCwAIBkMaH0kIkfbdu21RqL5eTkpAMps8emTZsAJCZmaU5N+i9iYmJC1iSgWJYyEaN79+4oV64cRo4cSe/LBCcfHx/V+2kz6SOtjaxSrFgxaiE4bNgwmjo1c+ZMiskvXLgwyx6RYsWKkWX4008/4bvvvgOgNMzJLobsQ58WpqamcHJyUmXMoxAizZybjDZC0QVSn6xcuTLdbeX6/P79eyqRlBazrlDfB8EwDMMw/0GMygI+ceIEXF1d8c8//9Brcsi5jY0NZQund1f59u1bil1euXKF7mTKlSuXmXiczpHDGE6dOgUANCVGzbaUnwI1atTQis8YKzKW1bBhQzrHa9eupfmsjG7QdavCLl26oEuXLjr9TllN0LdvXyqpMkS5YWrs378fTk5OFNfUR/tUackeOnQIly5dovnACQkJZEGmR6lSpYzGa6CJvvJ0jEoBX7hwAfv379d6TSotX19fLF68mF63sLDAlClTAGjX+rq5uWm5O4RGktnff/+drJbTUNy/f5/qbmNiYlCgQAFVuuqkheyTCihlIbLMRk1u374Nb29vgypemdzn4+OTqfIDWfJx6tQp+t1JRczohitXrmS2tMvgXL16FY0aNQKglKjJWtM8efJk6ftiY2Npetr48eMznLB4+PBhzJo1C4DSB/mLL76gUkhdJWA9ffoUgJJsJruGyb78krx586JYsWJar8lyIFm6JHny5Am9l/QzORF2QTMMwzCMChiVBTxo0CAcOXIkVXeFZjepd+/e0TxZTQs46Xaaz/ft26ezHtB3794FoPRMlgwZMoSSxSwtLREUFIQTJ04AAJYuXUolEyYmJvDy8tKpSyo2NpbuJpPO000PmbCmmaBhZmZGzU10iUyw27p1q1aoITXOnDmj1dtWk+7du+tUNkn//v0BKBbEv//+CyD95AtPT0+4uLgAUNx70mKXpWZM9ggICACgnJsbN24ke79ChQqGFkmLR48e0RSiZcuW6XRSkhACy5YtA6CUy9StWzfFyW4vX77U8mLFxcWRJ6ZXr16YNm2azud9u7q6AgA2bNhAr9nY2KBo0aLU2GLUqFGwsbGh92W5EZDYtEMT2VPaGBJmJbL5i64xKgVsbm6O3377jTrR6KITU8+ePam1nBxUrQt69OgBQPkByR/5qlWr8PnnnwMArK2tcf36da1WlLI2tHfv3jqP+27cuJEyhX/66Se60GTMR+779evXyT7r6OhI/5ek/z9dEhYWRjXZcvh1Vmjfvj0A/XXCkrFcTReeVK6apNWKUi44mt12mMwTEBAAPz8/CjclXROmT58OANR5zJDIdpoHDx7E6NGjqRZ5z5491I5RF+TOnZtc0OvXr4efnx/8/PzS/dzXX39Na0KfPn30Eve9detWsteeP3+Ojh07kjFy9OhROn+3b99GTEyMVj29JE+ePIiNjVW1R4MkNjaWBvfkzZsXderU0ct+2AXNMAzDMCpglJ2wZCeUhw8fUm3fu3fvko2loy9L4oL+6quvyHKpWLGiXjKfa9euDUDbAk5pIIR8r0mTJnS3rg/X7rNnz6jLy4IFC5Il/8i78+Dg4DTlbd68OQDgn3/+0XknmvPnz2c5BCATWIYPH07Z8Obm5jqTTZPLly8DAMaMGUNu+ZSsh9Qs4CpVqlDyoPSIZJAc1wkro2zdupW8NleuXCEPyYEDB5JZvbKP8YgRIzB06FAAipWoC9auXZtquCE8PJzWpnXr1tFvw9zcHL/++iu5m3VRP5waT548wfv37/HXX38BAO7du0dyDBo0CJUqVULLli0BKF64zPZPyCxyAMPQoUNx586dTH++bNmy5IGzsLDAwoULMWrUKACg2m81OHToEFq1agVA8QZu3bo1K1+Tc4YxXLx4UWuowqZNm6gIXwhBCrFPnz5o27at3rOdpYLbv38/LbaBgYH0fvXq1dG6dWtq1P/9998brBl7dHQ0nj17BiDRhbdnzx4AKStguYiVLFmS4p/6yEBMqoDlgpV0kZCZlVImIHHgQZs2bXQuV1rIqVkmJibw9PSEl5cXvScVcIkSJWjuKqC0KcxiBvl/UgGPGTMGbm5u1JAmPDw82c2hnBE9adIkmk4jmyroEisrK6pO0IzfHz58WMs1+vXXX1PpUr9+/fSu6Iydt2/f0pSyqKgoXLp0iapRZJMTScOGDVGrVi0AyvHWPM6hoaGZvWnVC4MGDaKqhsWLF2P48OFZ+Zqco4AZ5j/Af1IB//LLL9QdDlBuqGXuQt26ddGpUyeKqevK0k2Nw4cPUyJTQkIC3bjWr18fNWrUoJrebIyoY4yc+fPnY/LkyWjXrh0ApTwzi/FznobEMAzDMMYIW8AMYzz8Jy1ghlEL2XRn586dNM/57NmzqFq1Kg4fPgwAWn3qMwm7oBnmE4IVMMPkHNgFzTAMwzDGCCtghmEYhlEBtTphfaquNoZhksPXM8NkAbaAGYZhGEYFWAEzDMMwjAqwAmYYhmEYFWAFzDAMwzAqwAqYYRiGYVSAFTDDMAzDqAArYIZhGIZRAVbADMMwDKMCrIAZhmEYRgVYATMMwzCMCrACZhiGYRgVYAXMMAzDMCrACphhGIZhVIAVMMMwDMOoACtghmEYhlEBVsAMwzAMowKsgBmGYRhGBVgBMwzDMIwKsAJmGIZhGBVgBcwwDMMwKsAKmGEYhmFUgBUwwzAMw6gAK2CGYRiGUQFWwAzDMAyjAqyAGYZhGEYFWAEzDMMwjAqwAmYYhmEYFWAFzDAMwzAqwAqYYRiGYVSAFTDDMAzDqAArYIZhGIZRAVbADMMwDKMCrIAZhmEYRgVYATMMwzCMCrACZhiGYRgVYAXMMAzDMCrACphhGIZhVIAVMMMwDMOoQG6V9itU2i/DGDMmaguQRfh6ZpjkpHs9swXMMAzDMCrACphhGIZhVIAVMMMwDMOoACtghmEYhlEBVsAMwzAMowJGr4CfP3+O58+fo2nTpjAxMYGJiQly5cqV7CHfK1GiBDZs2AAfHx/4+PioLT6TReR537Bhg9Y579KlCyIiIhAREWFQeaZNm4Zp06bR7yzpw97e3qDy5GRiYmIQHh6O8PBw7NmzB19//bXWsT527BiOHTumtphGy6ZNm7Bp0yZ06tQJI0eOxMiRI9UWiUkFEyFUqSDI8E537doFAOjVqxfi4+MBAJ999lmy7eR7ZmZmyJ8/P/LlywcAaNmyJeT/cfz48ahcuXL2JE+DXr16Ydu2bQCA+vXro169eujZsycAoHHjxnrbb2aJjIwEANy7dw8AsHfvXnq+efPmVD/XvXt3AMD27dv1Kt/bt29pX76+voiPj6dzbmFhgcuXLwMASpYsqVc5pk2bhunTp2d4ex1cS//ZMqTIyEgcPXoUADBnzhycO3cOAGBikvyQlC1bFgDg4+Oj8+v53Llz+Pbbb7P9PQ8ePAAA7N69m9aw8+fP49y5c7C1tc3296fE69ev8b///Q///PMPACAqKgrDhw8HACxevFgv+8wp3L9/H1u3bqXnz549g4eHBwDgjz/+wK+//pqVr033elarDjjDjBs3LtlrFhYWGDZsWIrbW1hY4Ouvv8bjx48BAH379tWrfIBy8gBg27ZttGAEBAQgICAAf/75JwCgU6dO6NWrl9bn5Anv06cPOnfurDf5rl27hkuXLpGMT58+pdeTorng2dnZoUyZMvS8a9euepMRUBQvAHTp0gWnTp3Ses/CwgKAckOmT8V7/PjxNK1ZOzs7AECzZs0wbdo0+szx48f1JlNOJzw8HA4ODvDy8srQ9gkJCQCAy5cv60wBnz9/HgDQtGlTtG/fHgCwcOFClCtXjrZ5+/Yt3fzZ2dmRFR4eHo47d+7Az88PAODl5UUy5sqVC0OHDgUA7Ny5U+t60hX79+8HAAwcOBDPnz8n4+O3335D//79db6/TxU3NzecOXMGAODp6an1XkJCAuLi4lL83NChQ2FpaQkAydbw7GL0LmiGYRiGyYkYvQWcEqtWrdKrxZhZNGPNzs7OABTLe/369eSS9vb2TnbXJWnXrp3eZJs2bRrmzJmD2NjYFN83MzMji2/Lli0wNTWl90xNTZE7t+F+ItKCSGr9WllZkWu8WbNmetm3tGCTWr8pWbxJsbOzo+2YzOPj45Om9Vu2bFlUrVoVANC/f3861kWLFtWZDPXr1wegeHnkNXv+/Hl8//33AIAyZcrg0qVL5N41MzNDdHQ0gMTQg7SWhw4digYNGgAAOnfujLx58+pMzqQsW7YMkyZNAqBY4pUrV8acOXNo3wzg4OAAAPj7778ztH3Xrl2RJ08e8lBaWlqiUqVKepHtk1TAnp6eRvvjkq5vKysrTJ06FVOnTgUAXLx4keJCHz9+xPr16yk+rE83UefOndGkSRN6PmDAAAQFBQEAli9fjtq1a+stJpUZTp8+DUdHxxTf27Fjh95j6Km5kOX5YwVrOMqUKUOho4YNG6JGjRooVaqUQfbt7u6OgQMHAlBc0PLmuly5cvD390fBggUBAK1atcIPP/xAn2vRogVKlCgBQFHO+uLYsWN49uwZunXrBgBYunQpwsPDAQDly5fHsWPH8MUXX+ht/1nBz88Po0ePBqC4ye3s7OimJaUYvybyhqdjx44oXbp0pvft5uampXirVKkCIPFGWz7v3bs3bVOoUCE8e/aMwhsjRoygEJiuYRc0wzAMw6iBEEKNR4ZxcHAQDg4OwsTEREDJthQmJibCxMREuLq6CldXV7F+/frMfKXOWbp0qVi6dKmWbDY2NuLevXuqypUSVatWJRkDAwPVFodYv349yWViYiKsra2FtbW1OHXqlEH27+vrK3x9fek3lvRhZ2cnpk6dqm8x1LoeDXY9p8SOHTu0zv2kSZOy+5U6Izw8XISHhwtPT08BQDg6OgpHR0eDy/H69Wvx+vVr+j26ubkJNzc3ceXKFeHu7i7c3d0Ndq1kll69eqV6XWX0UbhwYbF69WqxevXqTO3bxcVF63uWL18uli9frqf/aTLSvXaM3gW9dOlSAEo2oXQHhYWFAQB+//132m7jxo0AgGLFimHevHn0etGiRWFubq5XGZ2cnAAANWvWJJn8/f1RsWJFyprr1q2b0brNjYG5c+dqlZdVqFABAGBjY2OQ/UsXs6+vL7mjNUuQZKazfG3q1Kn0GXZPZ49169apLUKqPH/+HADQr18/lC1bFrNmzVJFDpmLYWlpiTdv3pDrtlatWqhVq5YqMqXHzZs3AQAHDx6k17799lv4+/tTlnh6FCpUCADw5Zdf6iQMYWxrMLugGYZhGEYFjL4RhyayBm/fvn0AgCVLlgAA3r9/n2qTjvbt21NCR6dOnbImbSZ49eoVAGDlypX4448/6PX8+fPjt99+A4BUs2kNQbVq1SjT2d/fX68JI5mhS5cuKWbCtm/fHrVq1aI6vBEjRhhULnmuTpw4kWqilp2dXZpZ0pngP9mIo3bt2rhy5Qo9nzhxImbOnJltoXSBm5sbAOV3N3DgQKxatUpVeXr27Int27dTVri3tzc1JjEmIiMjKbHJ09OTEtR8fHxw7949SsKKiYnBixcv6HMFCxZEtWrVACiNdmRNs5WVVZbksLa2Ji8GoDTYkK8DoJ4IZ86coSTZDRs2wMHBIcXM53r16qF8+fIZ3X261/MnpYCTIg9eXFwcla6sX78ejx49okxfAHQSq1atSl2cNAvs9UFCQgKuXbtGmc63b9+mcgQPDw+0atVKr/tPjWrVqlEmp7+/vyoypISPjw9dsO/fv9d6Lz4+nm4afv31V8yePRsA9FrekRKaDTfSU8hZzJ7+Tyrg9evXY8CAAfTcWBTw/fv3qStWgQIF4Ofnl6oiuHnzJj58+AAAKFGihF4abgBAYGAg+vTpgzt37gBQsnilIdKiRQu97DOzBAUFYfjw4dRhTxMrKyuUKlUKAQEBBpHFzMwMMTEx9FxmPefJkwdA4lojq1fSo1SpUlStIa/xNMjZCjg1Ll++jKtXrwIA1q5dS8r5s88+w5QpUwBAyzo1BK1bt6ZYiK2tLc6ePWvQ/UuqVatGrShHjx6N7t27Y8eOHSSXjLnmyZMn3RIBXSNrffv166f1umYrSkCxlgFg2LBhRtHiM2l8WJOpU6dmxjL+TyrgnTt3okePHvTczs6O6unVOL+yrKdjx47w9fUFoOSbuLi44OPHjwCUGmHZYvKff/7Bs2fPqC64ePHiOHDgAADgm2++0bl8V65cwc8//wwAuHr1Kt2czpgxA2PHjtX5/jKLr68vmjdvnuY2NWvWBKBc8/qMYSdVwGkhyzGlt03y4cMHnDx5kp7LeHyDBg2wadMmyldJgXSvZ44BMwzDMIwaZCRVWg8Pg9K4cWPRuHFjrVIHd3d3g8pw6tQp2neJEiUMum9NmjVrpnUcUnv069dP3L59WzU5b926JW7duiX69euX7NzJx6BBg1STLyVkKZOdnV2yEiY7O7uMfIXa5USqXc9Dhgyh8wpAFChQQBQoUEBERETo4uszxdSpU8XUqVMFANG8eXPRvHlz8e7dO+Hm5ibKlSsnypUrJwCI4sWLi+LFiwtbW1vh7Owsxo4dK8aOHSsA0JqjL169eiVevXolhg0bpvVbK1myJO17+/bt4s2bN+LNmzd6kyMlLl68KGxtbemxe/du8fHjR3q4urqKkiVLipIlS4p+/fqJFy9eiBcvXuhFlipVqqRY1mRlZSXs7e3Fnj17xJ49e8SZM2fEu3fvxLt375J9R2RkpPDy8hJeXl7C2tpa63vmzZuX1u7TvXZypAs6KRs2bAAA6nADKE3X5fQVQyHjgSdOnMCOHTuom40hCQkJSdP9fujQIQBAcHAwChUqhJ07dwJQN770/PlzcrklHUM3Y8YMjB8/Xg2x0kR22kkaJ07nevtPuqAla9euBaBMLXv9+jUAwNzcHIcPHzZYt7b9+/ejY8eOAJQ8DjmA5MKFC3j48CHq1KkDAPjpp5/Qp08fAIrLGUjMSSlVqhS5MWXJpL6Ij4/H6dOnASjHzc/PTyt0JFtszp8/X6sjntrI6ULu7u74999/ASQeR12yefNmrFy5kp7L8zd48GBK9soMp0+f1jqO8+bNS8vtzy5ohmEYhjFGjL4RR05ClkGdPHmS7voMjbW1NVavXp3q+7Kca8aMGXB2diaLWE0L2MrKiu5iK1asqPXe3bt31RApXWTyTtLxhvb29vQeo43MhK5Xrx41THj48CFcXFzg7u4OAJTBr2tkBrOjo6NWkwiZaFWnTh38+uuvNAY1pfK9PXv20N+GqnL47LPPaEDJuXPnsHHjRuzevZueyzGL7du3R1BQEDW20BVyfbC3t6fM4pSQDYq+/PJLNGzYkEpJgcTSIH1YwA4ODjSMQRdkogQpQ/wnFHBKi7SsozMkmnNsDx06ZJSuU5ltnLSemskamiVJ06dP1ypl4g5aKVOrVi2q+S9cuDD27dtHne5k1zld8/DhQwDKoBRZ3lazZk1yQY8cOVJrUlhS3r9/D1dXVwBK1z5dLvqZ4eeff6Zwze3bt9G6dWsASpmNk5MTNm3apNP9yUEy9erVw6hRowAo4T0ANIFt165dVCpVsWJFDBs2jDKTixYtanTDIwyJUSpgGf8ZN24cvda/f/8slSSsWbMGLi4uALSVihrp+sWKFQOgjPl78+YN3XUXKFDA4LKkhlQW8+bNQ8WKFal5iNrI+GBSeOB4ziQ4OFjr+bJlywAosdciRYrofH81atQAoEwtk8ohMzfpx48fp1rSJk2aoE2bNjqXMbNUqVKFphCNGDGC1lVdItcuT09PGidavnx5lCpVigwfzSYr169fB5BYyrN8+XK9WL6p8fbtWwBKXkmFChXSvKlKCTmqUldwDJhhGIZhVMAoLWCZHXzixAl6bcOGDWjUqBEApXA/tY40ERER2LVrF919ubi4UOZpfHw8NUVQo32bdDkWLlwYV65coTvmrGTj6YOpU6fir7/+oufOzs7UQk5NBg4cmKIFvH79eqNoxJEW06ZN02rQYWdnx67nVHj06BEAZTiDrFyQvHv3DoDiHdOHBRwVFQVAiVFmlLi4OABKFzcHBwca+jJ//nydy5cWFy5cAADUrVsXc+fO1fIcyrVPX9UusjXnwIEDce/ePQDQav2YGn/++ScAoHv37nqRKzXkcBwfHx/cvn2bZv6mRUxMDFnuUm5AmWVcuHDhbMljlAp48uTJAJQuL5ptCc+cOQMAaNOmDSwsLKit2Lhx46h7UnR0tFabs88++wz58+cHoLiUZHxEDeQiEhMTg/z58xtFH+a4uDjqDjZv3jy6UCdPnqzVnUifuLi44MOHD1T+obmAAIp7TzN88N133wEwXKJLRtDsdpVWm8r/cgJWUFAQneNGjRpRD+CaNWvCw8MDoaGhAIAnT57Q71CW1Mht//nnnxR79GaHmJgYDB8+HICywEr3aFrEx8fTpLbRo0cjV65c9Bto0KCBTuVLD9lW18TEBCtWrKA4ef78+XHx4kV6T4bAdIlMAPP29qb9nj59GhEREVrbyeSvJk2aYPjw4WjZsqXOZckIMtYPJHY8Sw0Zw541axZ1ZgOUGD+glDINGjQoW/KwC5phGIZhVMCoG3FMnz5dqyl7ahOP0nqvQ4cONA1J3n2rwbt378i1fuTIEdjZ2SVrKmEo5JzOo0ePYv/+/Th8+DC9J70PEyZMoCEW+qZ///7YsGFDqpnXmr2gmzZtSuUe2XX/aCItVnt7+1SbrKfU6zkjSJez5gzhVMjRjThevHhBww2kuznVL9SwgJs0aUJJk7Vr19aqJtAFFy5cQL169QAok9batWuX6rZynfHw8KDr2dLSEs7OznrL0E4PmVhUrVo1hISEUHVFTEwMVqxYAUBxsXt6eqJDhw56lyckJASvXr2idaZIkSLU7zmrU410hQxlOTo6okKFCuT5kINgJE+fPqWhL7JXvkQO2sjAAIdPexjD27dvyW27bt066sokYw2ayAujQIECqF+/PmUwuri4UGxGX8hauwMHDlA25fXr13Hjxg1Ur14dgDI6Uf5fSpcujT179uikUbt0k6RWgxcVFYXAwECafHT9+nV4eHgAUEonTExMyEU/YsQITJgwAYBhM7Pnzp2LCRMmpKmApctq+/btOlW8Euk+zKqS1USOJ5R/ZyLmm6MVMKCEOQCkW4In1yVzc3McOXJE725dWV9eoEABqppo1qwZjRc9duwYwsLC6No5c+YMndcVK1ZkKJaobwIDA9GkSRMaCqHJyJEjsXDhQhWkMi5kLLdFixYZilVLZCikb9++GDNmDIDEgRJpfSy9DdgFzTAMwzAqYNQWcFLu378PADh79iw8PT21Brg3bNgQgGLFyXF1hkLWKA4bNizVEX4VK1Ykq2jp0qU6S8CS3bUKFy5M2dTS9QMortWkNZVfffUVACUhomPHjgZxS6VHrly5UrWA16xZQwlX+s7K1myUASRm4h8/flzLstVEh5nNOd4Cll2PmjVrlmo3uEaNGlGi3bhx48hDo0/kWtK1a9c0x9fJMXuTJ0/W6nBmLFy5coVqf0uWLEmeox9++EEvSVifKtevX0/XCpZr+RdffEH98zOZdPVpu6A/FeSsyB07dpCLo2bNmmjZsiWVNVhZWemlfGLLli0AgDFjxlCmqCZlypRB586dtWbslipVCgD0Ig+TLXK8AjZ2nj9/Ts1nHjx4QPE+GxsbNGjQwCiVLpM1bt68SfkkR48epZs+iWwQko1MZ1bADPMJwQqYYXIOHANmGIZhGGOEFTDDMAzDqAArYIYbi4/4AAAgAElEQVRhGIZRAVbADMMwDKMCrIAZhmEYRgVYATMMwzCMCrACZhiGYRgVYAXMMAzDMCrACphhGIZhVCD9ydNMMry8vKh/sr29PX766ScAQJcuXfD69WsAgIWFBYDEUWEFCxaEtbW1CtIyDMMYHjm17uDBg9Ty0dfXF6ampjQNy9HREaVLl1ZNRrVhC5hhGIZhVOCT7AUdHx+PRYsW4cGDBwCAVq1aaU308fHxQceOHQFAa7LJypUrs9NYmxg0aBDWrFlDz+WEnkKFCtFdn2ziHhQUBECZqDFkyBAAiUPvmUQeP35MQy08PDxo7qqVlRUqVqxI81Zr166NOnXqAFCO8RdffKFXuRYtWgQAWLx4MUJCQtC1a1cAQIUKFWi4+Jdffgk7OzucPXsWgDIr9uXLlwASJ2VlEO4FzeQIzp8/TxPMwsPD6Tpt0KAB7t27R1Ox4uLi0KdPHwCJw2F69OgBAKrOWH758iVdz0Di0Bs5kx5QvJqbNm2iWdUpeDhz5jCG9evXY8CAAfTc3Nwc58+fB6AMvt+6dSvev3+f7HPLli3Dr7/+mp1dA1AU/qFDhzL9OTluz8PDA+3atcu2HBll37598PT0TPa6n58fbt26Rc8rVqxINxApIX9gvr6+Ork4wsPDASgXXGBgIA0/1xzpmDt3bsTFxdFzIQS936RJExoXqA+ePXtG/8+IiIg0ty1evDgpXQDo2bMnAGDr1q2Z2SUrYJW4cuUKAKBly5b0OwSAhISEDH+Hm5sbACQbSSrX2KSvDxs2LEuyZoaHDx8CSJzYJrGzs0PZsmX1ss9t27Zh2LBhFI77448/MH36dK1t5DGeOHEirU1yeynXo0eP9CJfSixYsEBrjOuzZ88yvMZL+VMY65ru9fxJxYA/fPgAAMlOZkREBGrXrg0AiI6OBgCUK1cOAODk5IR8+fIBAAYOHKgXuT7//HP6OzQ0NNXtihYtCkBRKvpGHofDhw9j7NixuHv3brqfSUv5AkBISAgAYO7cuVi3bl22ZYyMjAQA+Pv7482bN7RAlStXDrNnzwagXIypXYj6mvt86tQpAMqIx/QUr+Tly5ckf9myZWmkHaN75Hzrc+fO0Wt+fn548uQJPS9VqhQWLlyY4e+UCur169daitLb2xuAMrpu1apV9LrmjaBEXj/pKeDq1asDyJ4C9vPzA6DcXP/www8AgL179+L169fYtWsXbSdvIOR6IDEzM6M189tvv6W1sWrVqlmWSZ6P//3vf8iTJw9Ziz/++GOybeVs4tWrV2PFihVZ3md2OHLkCLp37w5AWYvSmgMtyZ8/P+rVqwdAMfzc3d1RoECBLMvAMWCGYRiGUYFPygKWd6kyrqqJ5h2evb091q5dCyDREtYX5cqVw8GDB+m55l14UsqXL28QmQBgx44dAIC+fftqvV69enWKoaZFs2bNEBoaiuvXryd7T8ZssouMnV+/fh3Xr19Hy5YtAQCWlpbkwgWUO3RDIi2IgIAAes3CwgJ2dnZkzdy/fx83btzQ+pzMhv/zzz9RqFAhA0mbc5C/2W+//ZZi7/J6khaftH6TYmtri9KlS8PW1pa+IzOsXLmS/jY1NQWgeEBSCxWlZAFrIr+jXLlyZIVWr14dgwcPRpUqVTIlW1LOnz9P7s5Xr15hzpw5mf6O6OhoOqZ+fn64cOECAGQrpCNlioiIwK5duygPJz0M4RFMyuHDh9G3b1+qUklK5cqVU8wXsrCwQL9+/XQmxyelgM3MzAAkjwtqMnjwYMybNw8FCxY0iEzm5uaoWLEiPdf8W03mzp1Lf7dr147cQXny5KFYtLFgbW2Nd+/e0XOpiNVg3759+Ouvv+j58OHDAQCTJk1C8eLF6fXg4GBS1EWLFkWTJk3IrZYdl9R/lR07dlDyTenSpbUUreZzTSVra2uLUqVKAQC5ErOKjP+ZmJhgzJgxAIAZM2YkU27dunUDADRu3DjN75NliA4ODtmSKyWKFy9O+RMpIX9/FhYW+OqrrwAA3333XbLtrl69CgD4999/8fvvv2dLpmPHjiEsLAwAMGXKlAwrX7V4+PBhmsfQx8dHbzFyTdgFzTAMwzAq8ElZwM2bNwcAlCxZEo8fP9Z6T2ZFL1++HLlyGe6+4smTJ/Dy8gKglMV8/fXXBtt3amzbtk0ro2/o0KHImzdvitt++PCBMsbfvn1LGX12dnaoWbMmzM3N9S8wgMDAQK0kJrWoWbMmeVpiYmIo2czCwgI//vgjatWqBUCxxEaNGqWanDkBmbSzaNEi7Ny5k6xLV1dXVZszNGnSBIBiDcfHx6smR2pYWVmhV69eAJSKEE2aN28OV1dXAICNjY3eZXnz5g0AZf2VrnYZijFmqlWrBktLS0oEBYAaNWoAADp16oSSJUsaRI5PsgzJ2dkZ06ZN03pNxuu++eab7Hx1hli9ejUGDx6c7PXPPvuM3GMAUK9ePa14r6wDlvEhfdGiRQscOXKEnk+YMIFuDG7cuIHAwEB679GjR1qlSJpUrlyZMknbtGmjR4mBsWPHYsGCBQCUbHXpMlu3bh1MTU0pll21alW6UPSFLB1ydnbG7du36fW8efNSbWNUVBTF9O3s7GBtbU3uUFNT06xewP+ZMqQdO3ZQpnhwcDBcXV0xevRonQuWUeRNu4mJCd1keXp6qnozmBIxMTHYt28f3awkpUiRIlrhN3lMhw0blmbMOqvI0IDsewAAd+7cQaVKlSisVLhwYZ3vN6vcv38fgJIn9PTpU3rdzMyMcjoqVKigq92le8DZBc0wDMMwKvBJWsAxMTHo3bs3du/eTa+NGDECgOK+0rcL+s6dO7CzswMAvHjxIsOfk3XArVu3xldffUXJEk5OTjq1inv16oVt27bp5Ls6d+4MANTLVV+MHTuWXGdpYWZmhgkTJgBQCvz1SWhoKNVHys5cGcHMzIyOVyY9B/8ZC7hMmTKpZjR369aN3PuGyoCXXc00m3BMmTIlmadNLT5+/AgAmD9/PqZOnZrpz3fp0gWdO3fWeVKYbJ7Rtm1baoZkb28Pc3NzCjFonsP69evDycmJktQMzbx58wCAelFL8ufPn+Ga/0yQMzthAUrhtCyH0VwcN2zYkKz0Rh9It61mB5Vnz56luqikRbNmzcj9qgsX+tu3byl7c9euXQgPD6dmIe3bt6ftLC0ttZ5rMmXKFHh6etKNwfv37yk2qg+qVKmCO3fuAFDcgFKuatWqISoqio7xoUOH6Ebm/v37BnNvHT9+HIsXL6YyjdTKFySyfGX37t2ZubnK8QpYlhr99ttvGDlyJAClDCY4OJjKYgBQDLhr164YNWqU3mPCS5cuBQCSSWIsMWDZfCjpDUGuXLm0ynhkJj6gNM7R7ORVpkwZCtVpZvTrgtu3b6NZs2YAQB3hpFs6ISFBqzzT0tKS1ugxY8YYNN5frVo1kleT3LlzU44RoPxO8+TJA0AJPWXRfZ9zFTAAxMbGAlC63sg7VwsLC7i4uOik53NmCQkJ0VLA58+fpx+8t7c3KUGpaDSRF8STJ09UqYtLire3t5b15u7urpeSComlpSXFjFq0aAEfHx8Aid2D5ELi7OwMZ2dnAICLiwvGjRunN5lSQno8bt68icOHDwNQzruJiQl5ZDTboC5cuDAzyVo5XgEnLS+SdO/eXavPribbt2/PdplRRhkwYECyxCYAWLNmDfr3728QGVJCXove3t4oWbIkJZ22b98edevWTfEz586dw8aNGwEk1jn//fffAPSTKCXP7Zw5c5A3b15MnDgRgHLtyt7PYWFhOHjwIHkcNmzYgNWrVwNQ+rxLpacvZF8DGefPCNu2bcvq749jwAzDMAxjlAgh1HjolPPnz4tixYqJYsWKCRMTE2Frayuio6NFdHS0rneVZd6/fy8iIyNFZGSk2Lp1q5gxY4Zo1aqVaNWqlTAxMaFHmTJlxIYNG8SGDRtUlffAgQMCimUjAAh3d3e97evff/8VhQsXFjVq1BA1atQQL168SHXbnTt30rGytbXVm0xZ4fHjx+Lx48eiQYMGdNwcHR3Fx48fxcePHzPyFWpdj6pfz0FBQeLs2bP0cHV1Fa6urgKAcHV11cUuMkRAQICwsrISVlZWIleuXPRo0KCBOH78uMHkSEpQUJAICgoSAQEB4tmzZxn+XGhoqAgNDRXm5uYCgKhataqoWrWqHiUVonLlysLb2ztD2z569EhYWFgICwsL0blzZ3H37l29yvb27Vvx9u1bsW3bNrFt2zbh6OgoHB0dtdbgpI+iRYuKnj17ip49e4rg4ODM7C7da+eTvWCTMnXqVDF16lQ6aB07dhQdO3bUx650xsuXL8XLly9F0aJFtU64VMxqsnfvXoMp4Mzw6tUrUaRIEVGkSBHx1VdfqS1OisyYMYOOm7m5uXjy5Il48uRJRj6qtiI1mutZKuLSpUsbVAELIYS3t7fw9vYWRYoU0VLChQoVEmvXrhVr1641qDzZITAwUAQGBgozMzMBgAwVfZIZBSyEIIPDwsJCtG/fXnz48EF8+PBBjxImEhcXJ+Li4sS7d+9E69at6ZE7d+4UlfG1a9cy8/XpXjvsgmYYhmEYFVA/20dHyOzAOXPmIDY2luZ7GgI5Lu/kyZOZysCWhd+p9bVWEzmA2tgoWrQoGjZsCEBpqO7v708DsdVGDgnRbOxfvnx5g3XVyUnIhJ7g4GCtDNrg4GC9Z83KZiseHh6wt7en1yMiIqgs7cqVK5gyZQqAxPJCY0R2tpPDauQoRGPi559/BqBcKx06dEDv3r0BALNmzaKsZX0h++IXKlQIBw4coNdXr15Na6DmgIpVq1bR3GddkGMUsJrIrlgnTpyg1HtZJ5wSYWFhGDt2LDZv3gwgMZs76fepgcw2lpm8sqzBEB3GMkJ0dDRlvOfOnTvVFpu6ICoqimbAyqEMqREfH0/Zzknn0jIZQ7NESTNb+ty5c9SRbfHixThz5gwA6F0RN23alMqQkmZHu7m5wdLSEgDQr18/vXTMkrPFN23aRJnOsk1mRoiJiUk23UizU58+0ewylVGaNm2KmTNn0pzkDx8+4NChQ9mS4+HDh3TzkZkpVN27d09x37rOxs8xClj2htasezMUUoHGxMRQ44rBgwfD2dmZWp89f/4c/v7+AIAVK1akObZQrTKkhIQEKvGRg8i7du0KIHuDunXJ4cOHqeD/yy+/1Gvv7apVq1Iv7KFDh6Y6RerOnTv45ZdftOpY8+XLBwDUs5dRFKlszqB5rACkWoIkkdtv375dlT7R//vf//Dw4UMthTZjxgwAwNGjR3Hq1Cmd71OW/fn4+JCXx8vLS6vWNyWkjFOnTtWSy9bWVmvMp76YO3cuevbsicqVKwNIf3KUJkOGDMGmTZsAKL0e5Nqa2fIk2Tegd+/e1PTD19c3w5/38/PTavQk0XUDEY4BMwzDMIwaZCRTSw8PnRITEyMaNWokGjVqRNlqs2fPFrNnz9b1rlLE3t5e2NvbJ8uYq1KlCqXYp5Xmrvlo3bq1eP/+vXj//r1BZNdkwoQJWpnP5ubm4ubNm+LmzZsGlyU1GjduTMfq+++/1+u+ypUrR8fC399fCCFEbGysiI2NFQ8ePBBz584Vc+fOpQxTzceoUaPEqFGjMrtLtbOZ9Xo929raJjtOqT26desmunXrJoKCgjJ5CPVHRESEGDhwoBg4cKAwMTFJlh2tawYNGiQGDRqkdVx69uxJ1RNJH0ePHhXDhg0TpqamwtTUVOtzFhYWwsPDQ+cypkR0dLSwtbUVFSpUEBUqVBBLliyh6yY9Dh48KAoVKiQKFSokbG1tRVRUlIiKisq0DB4eHsLDw0OYmJiIggULioIFCwpXV1cqFUxKfHy8uHfvHj0qVaqktS7L7PFMlkmle+0Y9QUrhBDPnz8Xz58/F4cPH6YfWlJmzJiRTJHJei9D0KlTJ9GpU6cMK9mkj3z58okpU6aIKVOmZOhHmhIfPnwQEyZMEBMmTBBWVlbCwcFBODg4pPmZFy9eiBkzZmjVPWpetHv37s2SLKkRGRkpHjx4IB48eJDpz8pyCs164bCwMJ3KlxRNBWxhYSFsbGxE9erVRfXq1VNUGvJ8du3aNTOlR5qorUj1ej27uroKW1vbVBVx6dKlVSk7ygrdunXTKlHKlSuXzvcRHBwsgoODhZWVVYZvXJI+6tatK+rWrStmzZqlc/nS4ujRo6JcuXJ0DZUtW1aULVtWuLm5idu3b2tt6+/vL/z9/cXkyZNFvnz5RKlSpUSpUqXEkSNHsrz/a9euiWvXromaNWtqrbXW1tbC2tpaLFiwQPz111/i0qVL4tKlS2LOnDmprs/W1tbiyJEjWZEn3WuHXdAMwzAMowJG3wv6xx9/BKCUBMgZmM2bN0dERAT19fTw8KCs3c8//xwzZsygcoHUEmd0yenTpwEAjo6OuHv3boY/V7t2bQDA8uXLs52deOLECa3Ma1ka9cUXXwBIHH6+Z88eSmJ69OgRQkJCtL5HZhVPmDAB48eP1+mUJl9fX3Tq1AmA8n+W51YmLKVGTEwMNXr38/PD2LFjASRONtEXs2fPpvK2pJnqSalatSpNZ8pGokuO7wWticx6BpSMZkNNPsoOMsHpypUrmDVrFoDECUoyyUf+VrOLzN4NDg6mJKy3b9+mmWhqZmaGHj16AAAqVqyIMWPGAEj/GtMHb968AQBs3ryZpoNdvnwZCQkJWkNU5PCG3Llzo23btpQIKpO4ssPdu3cpmzlpJYOZmRkl9MlkWYmpqSnNVd6xY4dWOVom+PSHMciJR7KJeGqUKFECgDJ4WjYBNzRhYWHYvn07AKWGTTYgl8iLqGPHjvjxxx9pOEORIkWyve+1a9fC0dExW9/RqVMnrFmzBgBINl0SHx9PNX9///03ZXNu3LgRX375JdVTFilSBPJ3eeTIEcyZMwfHjx8HoIxHlAu3IW6u5FSpSZMmIbVrxdLSEgcPHkS9evWyu7v/lAI2VuSgA3ljrYlUtm/fvk02IUcO6tBnXfDhw4eT3TRr0rBhQ3z11Vd62392+ffff3HgwAEtZdihQwcAigGT2nS27CCH38ybNy/FgSkpMW/ePPz222/Z3TUPY2AYhmEYY8ToLWA5d3XXrl3k8jE3N6cuUoDS9EIOc5du3f8a/v7+NLIsLCwszW3lKDB7e3uMHz+eLHBra2u9W5UPHjwAoNTVHjx4kF7PmzcvyVWiRAlys8lxjt999x0AYNmyZTpxTWWWiIgInDx5kjwEd+/epUYMe/fu1YkXA2wBGwWBgYEAlK5Ha9euTXEbIQRZwKamphgzZgxmzpxpMBmZrHHkyBEASo1xWFgYWcQyZClp27atLtbCT98FzWQcWXy+YMECmgNas2ZN1KlTh2LMVapUoXZ0+nAzM9mCFbARIYTA8uXL093OwsJCr7OymU8WVsAM8wnBCphhcg4cA2YYhmEYY4QVMMMwDMOoACtghmEYhlEBVsAMwzAMowKsgBmGYRhGBVgBMwzDMIwKsAJmGIZhGBVgBcwwDMMwKpBbbQFyEqdPn6apH4GBgfjpp58QFBRE70+ZMgWAOpNJPjXk8AV7e3uYmJhg/PjxAIAxY8YYbQcv2ag/KCgIt27dAqBMn/L09ASgdFa6cOEC6tSpo5qMxsjr16+xevVqrdfkZCTNCV8AsGHDBhpGsGXLFmpJ6+bmBicnJ/0L+/+8ePEC9+7dAwBcv36dWqamRHBwMAClrerff/9NLWMNyfr16zFlyhQ8ffoUANC6dWvs3LkTAFCgQAGDy8MoGLUC3rp1K3r37k3PZdeupFNI0nrP2dkZP/zwAwDoYlpNMuLi4mhk3axZs7T2rzlNRQhBk4DU6GUsOXbsGL7//nsAyti8LVu2qCZLUiIiIgAAXbt2pbFvJiYmMDExwb59+wAAI0aMUE2+pEiF6+HhgVOnTtH5fvz4Mf0ONHsGM4nMmTMHc+fOBQAkJCTgw4cPWu/LMZhmZmb4/fffsW7dOgDKzU1cXBwAZWrWpEmTAACDBg0yiNzyGtacSpTS+c2TJw8ApU1lmTJlAABr1qzJ6li7DBEXFwcnJyeawvb69Wsao3n16tVkIzXl6FFGm4CAAFy4cIHWoMuXL+P27dsAFIPg2LFjOtsXu6AZhmEYRgWMshf0rl27AACDBw/WmtsYHx8PIOU5sGm9Jy3g/fv3Z1Hc1Dl06BBatWoFIG1rp0qVKjh//jwAZZqTWrx8+RLW1tb0fPfu3ejUqRMAICoqCl5eXlrbSxegnN2rL3x9fWmilbe3N70uhEDv3r1pEpa0JtRm5syZFFIwMTHROveaf3/zzTeoWrUqAKBx48bo0qVLWvNiP1VTOcOLyOzZswEAM2bMQExMDL3epEkTVKhQAQDQokUL8nzJ4yjPu729Pfr37w8AqFSpEooXL64D8VPn0qVLAIDFixejRIkSWLp0KQAgOjqavG6VK1dGtWrV6DNt2rRBlSpVACjn3FB4eXmhY8eOWt5A+VuzsrLCjz/+SNu2bt0a9evXN5hsly9fBqAMt8+fPz8OHDgAIOU1MyVv5sCBA9GvXz+dyhQSEkLhAU9PT3LJP3jwgKaxJcXKyorCHhmYgJbu9WyULmi56BcuXDjdwckZQboS3N3d0adPn2x/nyZpuSMqVapEw6ZtbGxUVbypMW/ePFpUrl27htDQUHpP022+fv16vcnQv39/7NmzB+Hh4cneW7x4MZycnJArl3E5a+7evUsLRNJ/Bw8ejM6dOwMAWrZsqY6ARoinpydmzJgBAIiJicHYsWMBAP369YOVlRUKFy5M28qRgF5eXujbty8tviVLljSYvAEBAWjatCkAReE2atQIzs7O9L68EciXLx/y589vMLmScv/+fQCgiUy1atUCACxfvhzly5cHYNjjlhLNmjUDkBhmkiGD/Pnz003ON998AwCk/DSveTMzM53K8+eff+L3339HdHQ0AGWta9SoEQAlBJbajX7btm11NXoUALugGYZhGEYVjNIClm4TmciQEu3bt8fjx48BAG/fviVL88SJE7h27ZrWtjLB4927dzqT8dSpUwCglcRkZWWFrl27AgB69eqFevXqpfl/UINDhw5pPffz80szSUgOndcHMnPUw8NDy/qtVasWVq1aBUA/iXO6wNXVleS/c+cO8ufPD3d3dwAg65fR5v3791puZ+mZcnFxSbbtb7/9BgAYPnw4ypYtaxgBkzBnzhxERUUBUKzcpUuXwsbGRhVZUuP169fo0aMHACA8PBwDBgxIllGuNhcuXCBPZpcuXbBs2TKtMJgarFixAgsWLED79u0BKN4rNWQySgWcGnIxdnZ2xjfffENZqJGRkeS+uHXrFoKCgiiWuXLlSvqcVNK6ICwsDEBiiQGgxAUHDBigs33og71792Z4206dOpHLUB/IizJpmCEqKoqyW2fOnIkSJUqotginhoeHB+7cuQNAuXjd3d1Z8aZDixYt0LBhQwDA2bNnKbN0+/btpEQkai/QgJIvIRk+fLhRKV+59n3//fe4evUqAOXG1ZiUrzSEzp07RxnXLVu2NIpz+/nnn6NDhw6qy2KUSViSSpUqUXwDAOrWrQsA2Llzp+oLslRkmouuv7+/lsX24cMHXLlyBYBSkiT/L1999RXu37+PqVOnAjBMfObixYsAlKQQeVcPKLGPcuXKAQCcnJzw5ZdfAgAlZukTuYg4Ojri5MmTKcb7hRBwcHAgK+mLL77Qu1xpceHCBQBKoo1coIsXL44XL17o4utzfBKWLJHp0aMHzp49CwAoVKgQVq1ahW7duulHuiyyaNEijB49GgBQoUIF3Lp1i8qj1MTHx0fL6pWMHDmSklEBJabavXt3AIYvOQoNDcWwYcMAKOugXOvUroGXMd+WLVvCw8NDp/HcFEj3euYYMMMwDMOogFFbwJUrV8aDBw/ouby7s7OzQ/PmzTF58mT9SJcBUrKANVPX/f39MXDgQFy/fh1Ayun20l1tCLeRTLHv2bMnvbZ+/XqEhoZSdva3336LGjVq6F2WlDh+/DgWL14MQClJktmS8rhJy9zLy0vVRiYym/P06dOUq+Dt7a2rO/scbwFLQkJCyOI9d+4cChQogA0bNgBQ4oTGQFBQEHnaTExM0K1bN4rzq2kJt2nThkr10mtKVLNmTQDAgQMHDJoJvWzZMmqa07ZtW2qkozZyPe7SpQvu3r1L+UFXr16ldUWHVnG617NRK+BTp06hefPm9Fyz1jd37v9r77zDo6i+Pv4dIJAYSpAkBEGJICWCGhSIAoEEpUSkBTFEQECCEDoCoQiGLk2KdBWQIi2UINJEJKFIiVKkJBCRGkoKSEuAX8h9/5j3HnY2u6mzhXg+z7NPdnZndk52586559xTimhCxQ0vuvLly2PRokUAVJelJUqtmVPAsgRhmzZtqFSdlM9csJOx61pv0tPTERAQAECbNuXi4oK0tDRyy7i6ulLZxDp16qBIEduECOzdu5cGSt++fTXfW+XKlSmfu2rVqlaVq3Pnzli5ciUAbY5lYGAgevToQfm++UhJ+c8oYADktm/Tpg2OHDlCSm3dunUUHGNrZBqPDPiUk/4RI0bYrKTsN998Q8rNcGw4OjqiZs2adC88fvw43TM7dOiAH374wSoTh3v37qFNmza0xPDo0SOa5IeEhMDb2xuffPKJxeUwhbx3fPTRR6hTpw5VM4uPj6ec8mrVqqF///6UQliyZMm8no5d0AzDMAxjlwghbPHIEYmJicLf31/4+/uLIkWKCEVRhKIookiRIpke5t7r06ePmD17tpg9e7Y4fvx4Tk+dLZGRkSIyMpLOqyiKOHHihHB2dhbOzs6a1xVFEQCEj4+P8PHxEQcOHBA+Pj703uLFi3WTyxQnT54UhQoVMvlQFMXk66dPn7aoTDnlq6++Ek5OThrZmjZtKpo2bWp1WWrXrk2/mfzuDJ/XqFFD1KhRQ2zYsCGvp7DVeLTKeDZHcnKyqF27tqGgkBoAACAASURBVOY33rFjh9ixY0d+Pzrf3LlzR9y5c0d4enpqxvOIESNsJtOKFSsEVK+DUBRFVKhQQVSoUEGcOXNGs9+aNWtEqVKlRKlSpYSiKGL+/PlWlXP37t1i9+7dIiIiQvTr10/069dPuLm5iYoVK4rJkyeLyZMnW1UeIYTYvHmz2Lx5M313Li4uwsXFRXTr1o0e1atXFw4ODqJ06dKidOnSol+/fnk9XbZjx+4H7MWLF8XFixc1Cis3CtjwvTlz5uThOzSNVMByIJh7eHh4CA8PDxEaGqo5/qefftLsFxcXJ+Li4nSTz5CsFLCfn58ICAgQAQEBdqmAhRBizpw5mptflSpVRJUqVcSFCxesKseZM2eEm5ubcHNzo0mVHMjyr6Iows3NTVy6dElcunQpt6ewtSK1iQIWQojFixdnmrACEFu2bNHj4/PNkSNHxPPPP68Zs4GBgSIwMFCkpqZaVRZDBQxAdO3aVXTt2tXkvo0aNRKNGjWifW1NVFSUqF+/Pt1nrP37jho1SowaNUoAEMOGDTO739GjR+m+WLp0aXHo0CFx6NCh3J4u27Fj12vAWZGQkICePXvStmH5sujoaE13Ffk/KopC67IyqCevyCCh0aNHU6eWu3fv0ppMqVKl4ObmRrVvZYEOSVJSEuUuX7lyhdKVZBk5vZk+fToAdX2ta9euANR1IcOAg7Jly1Jq0Pz589GrVy+LyJJbHj9+THWC5ZoNoNYTHjlypFVlke0lk5OTNa9v2rSJfmshBJYvXw7gaXnAHPKfWgM2JCMjg76z7t2705gtVqwY/vnnH5vnawLqPUfWqN67dy/J2KFDByxbtsxqgVkrV66kkrovv/wyDh06BAAm62LLNU9ZA8FcjWNrcuLECQpmVBQFhw8fBmCdmI4FCxYAUDtT7dq1K8uAK5lmOHr0aBw8eBAAKOc6h/AaMMMwDMPYI89UJSxDypcvb7a70YoVK+i9jRs3aqKnZXT01KlT83V+GdU3c+ZMtGjRAoDaxUk2265bty48PDzMHu/m5kYpDleuXMHq1asBWM4ClqX95F9TyN67ADTFOmxN0aJFMXz4cADafsBbtmyxugUsI++Ni7Vv3LiRLCIbeZWeaQoVKkSRsUIIzJ07F4AaydujRw+6bmWjFr2RllHbtm3Njtvy5ctj/vz5ANRxJFOB1q5di4yMDKulKL3++utkLQ4YMCDLjlC2TNkzh5OTE91nnjx5grS0NKudW3pNQ0JCsi0TLL/XiRMnUjrXmTNnNJ2v8sszq4CzIigoSFNByxBZojK/CtgQ2eBe/s0LslWhLZA5eoadkOyti4+pVICTJ09i9+7dePfdd20g0VNiY2MxadIkTUqInoP0v4LsftOtWzf6vTt27Ijt27dT6depU6fq3uJv7ty5tETTpEmTLPeVv+vGjRvJrfvrr78iIiICX331FQDQcomleP3116kManbYS/6tISkpKUhPTwegKuMyZcpY7dzyGstNdzVXV1eqFhgTE6Pr2GYXNMMwDMPYgAJpAc+ZM4cCYozRsyGDnsjCE7ZAegUyMjLg4uICABYpXqI3aWlpFAyXXyZMmAAA8PT0pEpM2RXUMKwLbeh2HjhwoM1r3torMpjl6tWr9B2ZCoiUzeOvX7+OsLAwCtRp2bIldu3aBeBpbfj8cuzYMQQHBwNQ67TnBEdHR3z55ZcAVAsYADZs2AAA1OfYUly4cAE//vgjnSurXrmyqxgA+Pv7W1SunHDw4EGMHDkSqampANQlvAoVKthYqqx58OABeQelJ0YvCowClq3hxo4dS60CjenVqxcVBc8v8geJjY2lddvcVExJTU3VNB+QzaAtwerVq+kGY8yECROwdu1aAKo7SJastHSzi9u3b9MajFxPN8fNmzexcOHCTK8XL16cJgz5ITY2FlOmTAGgDjbp3suqE1RsbCwV6k9OTtasn3NXJNMsWbIEAwcOBKCWPd25c2e2x/Tt2xdCCIwYMQKAmmkwceJE+jw92mVu3bqVMgNyg4ySlZOvrNZi9eLcuXNo3Lgx3XOyUr5Dhw7FuXPnNNt6Eh0dje+//x6A2mRBTqhkhLM899atW6n15O7du5GamorPPvsMAFCrVi1dZbIEZ86coaYXucxqyBa7VsAPHjzA3r17AUCjOMeOHQvgqeW2cOFCTaqRMbJkYNOmTfNTJlDD/v37Aag3W6msQkND6QfKqmvP3bt38dlnn2n6FusdLCHTsDp16mR2jXTChAkYPXo0fWfVqlXTlP60JH/++SdmzJgBAKhSpQoqVapE684eHh50Y42NjUW3bt1ogmWIn58fDfb84OrqStfI/fv36QbfpEkTNGzYkPZLSkqiUpSTJ0+mG7CiKJp+wL6+vvmWqSCxbds2AGpLPxlwU65cOQqoM053c3d316wL9uvXj26Ao0ePpnXNnj17Yt26dfmWr0WLFmRRdurUKct66HLt8siRI1TLXVEUFCtWzKLlM2VQ5IgRI3Dt2jUKADPFpk2bAADz5s2jsf3xxx/rHisRHh5O92f5/QGmy+5KK7dGjRoYNWoUPvjgA11lySkyjTEnaW1RUVEAgB49esDNzQ0A6K9e8BowwzAMw9gAuy7EER8fr4k4M0wnMiar9zZu3AgAus5Q5ZqUn58fNTMQQlB6QL9+/dC8eXNaU0pJScHu3bsBqGuEN27coM8SQlCajYykzC+DBg0CoBZuv3z5MnVC+eOPPxAWFkbP79+/T6kdS5YsoWg/ayAto2nTpuGPP/6gdaG6deuSR2D58uWZZtOyqXtERESWqV65QTaHf/XVV+l8L730Enr06AFAXR9fvHgxFeVXFEXjdVm/fr0erucCWYhDuvSbN29OhUyy4s0336RxL38LeZx0ZQKAl5eXLrETx48fR9++fQEA//zzD3r37g0A6N27t6ZQw+HDh2m5ZtasWfT7V6tWDRMmTMhUbEdPvv76awBP3cjSM2OYlrVz507cunWLXL+KolDhkO+++073nsAnTpygDmaGjWcyMjI0UcYhISF5cvHrTXx8PKWJ/vbbb3jxxRfN7nvx4kX6jv/3v/9h9uzZAED9lXNI9uM5J+WyLPDIEcHBwbkuN1mkSBFRqVIlERYWJsLCwsTff/+d09PliRUrVmjK5xmW0ytevDiVLnRxcclUH1o+vL29xbVr18S1a9d0k+ujjz4SH330kShUqJAIDw8X3t7ewtvbW5QoUUJTcrJ9+/YiNjZWxMbG6nbuvLBs2TKqW5tVreq3335b3Lx5U9y8edMicjRs2NDk7wmDkpMAhLu7uxg/frwYP368nqe3dUlJi47nVatWUe1dR0dHei63jX93c3XKixYtKooWLSpGjx6dy6/XPLdu3RK3bt0S9evXp3O7uLgIV1dX4erqKtzc3ISjo6Nm3Moyj3qOW3OsXbtWrF27VhQtWjRTGVRTdecBiGrVqonExESRmJhocfmeBZKTk6k0cEBAgIiPjxcpKSn0OHr0qDh69KjYsmWLaNWqlfD09BSenp5i9erVeT1ltmOHXdAMwzAMYwPs2gWdlJSEoKAgAGpv4KzczNKFpCgKRo4cSUE1liYtLY3cUt26dTPb81eYCEyQfP/99/j00091lUtG6M6ePTvTuWvUqAFAdZNLF6s9IANtZs6cSYF2QgjUr1+fgjZCQkIsmrh/+fJlfPfddwDU6EfZH1l+h7LyVo8ePTJVw9KBAumCNkV0dLQmgO7nn3/G6dOnaVtGPRuPmT59+lD6kSV6yt66dYuWlzZu3EhRvoqioGLFipSi1q5dO1oKsSYHDx7E8ePHqdeuoijYs2cPADUozTA1691338222tN/DVnJbNSoUbh9+7bZ/SpWrEhLhvnoG5DteLZrBQyoOb2AqlCkAu7Tp0+mKLpmzZrpKN6zj4yC7ty5M27fvk2RnU5OTtRUPB+NphnL8J9RwAxjS3766Sd069aNUqcMo5vLly+Pfv366THB5mYMDMMwDGOP2L0FzDD/IdgCZpiCA1vADMMwDGOPsAJmGIZhGBvACphhGIZhbAArYIZhGIaxAayAGYZhGMYGsAJmGIZhGBvACphhGIZhbAArYIZhGIaxAayALcTBgwexbt061KtXD/Xq1YOiKBg6dCiGDh2KdevW4erVq7YW0a4YM2YMFEUx+/D394e/v7+txWQYhtENVsAMwzAMYwOK2FqAgsSMGTOok8rhw4dx+fJl6tykKAo1r37y5AkiIiJQoUIFq8gVHx+PunXrAgD+/fffHB8XGBiIlStXAlCbOFgKf39/REVF0bafnx/Cw8PpOaBayID6PdqifOr69esxceJEVKxYEQAwbNgwvPPOO1aXg7Ff5DUsr1lL8r///Q8AkJKSgv79+wMAtm/fjtq1a6NOnTomj/Hz86OG9Ix98MzWgt67dy9SUlIAADdu3KCb8oULF/D1119r9u3Tpw8A4NVXX0X37t0BAEWLFs2vCIRs/Tdr1iySQyoK2U7N8Hn79u0xaNAgvP3227rJkBX79+9Hw4YNTb6XVZtEBwcHahH3yiuv6C6XvGEZu5ZtdE2aZO7cuQCAwYMH000PAIoVK0at3hRFwZtvvol27doBAF588UW0bt06L6fjWtBQW3zeuXMn2/0KFSoEd3d3PU8NALh58yYAoE2bNjhz5ozmPcPxbczjx48BqPeWhQsXAgCCg4N1l+/vv/+me87WrVszyWduPHfp0gVLlizRXR49SUtLM2kklCtXzgbSPCU9PR3A05apEgcHBxQvXtzcYVwLmmEYhmHskWfGBb1kyRJ88803tH3t2jU8fPgQgNr71nBmajwDlE2YAaBjx44A9LOAZ8yYQa7lwoULU8/iwoULw8fHB4MGDQKgnZlKS8lalClTBiVKlACgzuBkH+Dp06cjPj4ejo6OAIC33nqLjomPj4ePj49FLF/J2LFjNdvS7Wwv7Nu3D0OHDgUAjfULAI8ePaLrT1EUREdHIzo6GoBqHXt7ewMA1q5dq0df0f8Ev/32GwB1ueHAgQMAsrboihUrhvbt29O2l5cXAgICAABvvPFGnmS4fv06AgMDAYCWkwzJygKWPHr0iCwmvYmIiEBYWBguX75Mr4WEhAAAPvzwQ+zduxd//PFHpuPq1KmDTz/91CIy5Yb4+Hjs3LkTR48epdeCgoIAAL///jv27dunWY6SZGRkWFSuhw8f4vbt27R9/vx50jfJycnUX/3IkSOa49zd3cljkheeGQU8fvx4zUWXG6SLoF27drqtZV65cgWAujYoB+WTJ09oXXfdunVWczFnh5eXF1544QUAwNmzZ+m5HLi2olGjRgCeuqKlQpbrvbbm0aNHePTokcn3atSogVOnTpk9Tt68jx49ygo4Gx49eoQRI0ZQvIFcWsqOhw8f0jEA8MILLyA1NRVA3hXw6dOnTSreN954Ay+//DJtv/POOzTWIyIiEBUVRa7TkiVL4sUXX8zT+bNj+/btuHTpEk0AFi5cSE3l33rrLTRp0sQi580vCxYsAAD07t070+Tlhx9+MHmMu7s73asshbxe3n77bZw8eTLXx0uDLq+wC5phGIZhbMAzYwFnx/DhwwGogRnGdO7cGQBQrVo13c536NAhAEBMTAzN6AoXLkzPZUCWYRCWdEdb2zL+66+/yGK3J6Sla+yKfha4e/cuPY+KioKTkxMF7Pz444/k7pNWPpMZOWZ//vlnxMbGat6TruWmTZuajeo1dk+7uLjk2/I0XK4CgHr16gEANm7caDbgKzg4GB9//DG2b98OQM0esFQktDyHZPjw4bTs1bBhQ4wePdrs92Ur5s6dS0FjWfHGG2+gZMmS5L0IDQ2Fl5eXRWX76KOPAEBj/VasWBHPPfec2WM++OADAKoXJI/BlsQzEwW9cuVKdOnSRfPahg0bAKiuF0u5fMyxbt06AECHDh0yRT4bPjcVBe3j42PVNKT9+/fD19eXtl1cXAAAr732Gvbt26fZV743fPhwDBs2zCryRUVFZYqE3rNnDwDrpHSY49atW9iyZQsA1dV3/vx5JCcn0/vytx4xYgRCQkJQqVKl/J6ywEdBX7x4EQAwbtw4ch+np6dDURRK8fryyy/xySefADA9obYE+/fvB6DeXA0nVzIuQa4tm+K1115DWloa/vnnHwBA7dq1LSZnTEwMWrVqRUo3OTkZzs7OAJ7GwrRo0QKAGp9StWpVi8mSHTICfNOmTRQhXrVqVbzyyisoXbo0AKBnz560/+uvv07xKdbgypUrqFmzJgB1Qi0Ntfnz52cV2Zwbsh3Pz4wC/u2332i2If32cnbas2dPdOrUSUfxskdWsjp8+DBZw4qiUL6toig4dOiQJvdX5gQ/efIE9erVo0FvaXr37k1pEcZkFeQycuRIsk6l7JZizJgxWVrCUhE3atTIZmvEf/75J/7++28AQL9+/ZCUlARA/a3btGmD1atXA1CDg/JIgVTAN27cAKBOVJYtW5b5YCEQHByMSZMmAQA8PT31lzAbNm3aBCD7AElTQVjvvfceihcvThPqgQMH6jEZyxIZMLR161a8+uqrAIAVK1Zg9uzZJFv37t0xe/ZsAJbN4zfFlStX6F5oGKR0/fp1lC1b1qqymCM8PBzjxo2j7fv37wMATWh0gNOQGIZhGMYeeWYsYECNOAZUF4FM+ZBId2nFihU1bg174eDBg+jQoQMA4PLlyxp3dUREBD788EOLndtUahagflfe3t6UhlS/fn3MmTMHgJouIITAL7/8AgAWj66MiorKFA1tDmkNh4eH28xFfezYMfquli1bBiEERo4cCUB1oeYxza1AWsDdunUDACxfvtz0wUKgQYMGtAwRGBhIVp0sdmJp5Npq27ZtyV1qipykIZUqVYrcmZMmTdLLnZkjGjdurLk3ysJDc+bMyY9nJtdERERQepEh33//PZ577jm6F9qKO3fuoGXLlrQEN2vWLAwYMEDv0xQcF7QhDx8+RP/+/Wl9LjExkQZGw4YNTeaR2QPSVb1hwwbMmjWL1nEs6Y6OiYlB3bp16YZRsmRJjB8/HoB6YzS+OVy7dg0A0KBBA1y4cIHW1vOaApYXoqKiSAln91vaQ9Usd3d3zdrw4cOH8xoIUyAVsJwcT58+3fTBJpZBhgwZAgCYMmWKHvLlmIYNG2rGopycygmVvN7GjBlDQXcRERGaz0hLS6O88aZNm2LHjh0Wl1vyv//9jybzP//8M73+66+/WrWZybFjx9C4cWMA0FQ1E0KgSJEiqFKlCgBg9OjRFqkWlh0REREUgAUA8+bNQ2JiIoCna/iVK1cGgPwEgrELmmEYhmHskWfSApZI19a2bdsoIKZUqVKYNWtWpohpeyMoKIgiqRVFoco/ehf4X7JkCbp3704WxrfffpujAhy+vr7Yv38/RSWePHnSpgUl7Llu9J9//ol3332XomfHjRuHUaNG5eWjCqQFLK3BuLg40wcLge3bt1PdbemFAYC+fftiwIABFg9qkly8eBFr1qyhbZlyIqNlc8KGDRsooOzMmTPk3rbWcokMFGzatCkuXboEQA1elJXGrIUMlp01axY9nzhxosbbUbhwYXTt2hWAunRj6WwWWSylWbNmmapaGWNcKCgPZD+ehRC2eOhKaGioUBRFKIoiChUqJEqXLq33KXQnKCiIZC5SpIgICgoSQUFBup/n7Nmzolu3bmL+/Pli/vz5OT5u+PDhAuqNVQAQYWFhusuWF8LDwzVy7dmzx9YiCSGECA4O1sj166+/il9//TW3H2Or8WgX4/nWrVvi1q1bYurUqaJEiRKiRIkSQlEUUbVqVXHhwgVx4cIFvU5lcRYvXiwWL14sAIhJkyaJSZMmWV2GnTt30j1GURSrnz8rzp07J86dO6cZMwEBAVY7/4kTJ0SvXr1E/fr1Rf369UXHjh1FcHCwCA4OFh07dhQeHh4k16JFi/J6mmzHToEoxDF//nwqdQaoXUlkOTkfHx9biZUl8gcA1LQk+VxvqlatmqcOKHImKmer8fHxusqVV/z8/DRBWlFRUTbNFZY0b95cYzllFaTDmEbmhg4dOpR+U39/f8THx1Nhk507d1otMCs/NGvWDIB6HchUlxEjRlhdDktch4MHDwagenrymrLj5uYGAKhVqxaOHz8OwHo534Cac2yoM4wJCAigtXtZB9oS8BowwzAMw9iAAmEBA6CouvPnzyMtLY1mN97e3lYNv88phqlBhQsXpjKV9oIsKmFv2IO1mxMmT54MABQJyuQOGUX+5ZdfYsSIEZRaExcXh9dee82WouUI+fsDMNvQw9rExMToUqZyxowZANTuRdKqb9WqVa4+Q5Z69PDwoNekB8Qe8PLyIgvYuBOanhQYBSwVWN++fQGoVWEAtYuStctUZsfnn3+OdevWkdt59erVdtM5yRyy44qtsZdOSdlh3LibyRuhoaFYsWIFpfzozZYtW/Dee+/pWinq0KFDOH36NG3XqFFDt88+depUrgLCDNGrRnSfPn0AqKk8Mt+5S5cu6NevH4CnxlBWyAAowxQtveo3ZGRkUO17Wd40N9y7dw9Lly6lbUvWQGAXNMMwDMPYgAJjAe/atUuzLetEW7O4d1YcPHiQ6rKuW7cOhQsXpkIc9hSwI9MWZK9bWYhApmPYGuMqWc+KS5rJGzExMRaxfmUP2h49emDYsGGYMGFCvj9z8+bNANT0SJnuAuS/Z6whrVu3xuDBg9G7d+9s9/3jjz/ouZ4dkmS6WJUqVcjVPnfuXPz4448A1KpbrVq1MlsB7MSJE/j4449pu3nz5gD08xT06tWLLNjff/89x/+7LBgyZcoUPHjwAG3atAGgdZPrzTOtgGXe5d69exEZGQlAVWZFixZFjx49AKh5wXpw8OBBAKpiHzJkCBUaB562TjPe/+rVq5g5cyZtG3ZG8vHxQWBgIIDsC8Bbi5SUFKoOI28gcnB4e3tb7LyGZShNER0dbfZ9SyjgW7duAVCXCmQ0a/Pmzc2uUd28eTNTRKWM2mWetvjLidIwPkZWmZKuRFdXV11kkk0hnjx5goSEhHx91l9//YUZM2ZQZT5D5VutWjVdKz2lpqZi7NixVAPB2HX+5MkTOp8s3Qsgr3npWTJgwABaOhs6dChVEOvUqRO8vb1NKmAhBC5cuKDJ9e7fvz8A/daA69Spg++++w6A2opWLltlVf7y33//pe80MjISXl5e1KDDkti9Apazkjt37lDourzojh07BgCZejIOGTKE2pnphVSeQ4YM0ZSRLFy4MF3ohvWdDx8+jMuXL1MXIUVR6LmPjw/WrFljsXaEjx49ohJ+Hh4e+Oyzz7LcX3ZWad26NWJiYkjerl27WqwUoL+/f54T3KXSlS0L9UYG/CxfvpzqF7ds2RLTp0/XrG/J8pOtWrWi7w1Qu6k8C4FC1kIq0cKFC5td57tz5w4V6hg/fjy2bdsGQL1hly9fHlOnTgUAlCtXTheZpJLav38/9uzZg9GjRwOAxjKrUKECSpQoQduJiYlISUmhbXn/CQ0N1az516pViz7v9ddfz9M6pDkCAgLwww8/kFW9bNkyjYzR0dHUplV26QLUjk2WQKZ57tixg7wIixcvptQiY8T/lx2VMi9atIi8lXrx3nvvkTI/e/YsQkNDAagFc2RZyUuXLiE1NZU6de3atYu6NgUEBFCgmaXhNWCGYRiGsQF2X4pSrjGsXLmS1lgqV66MMWPG0DrOlStXNF1KfvzxR4t125BdjWRzAkOr19RzaTm3b9+eIrUtHfE8Z84cTWePKVOmUGNuDw8PSp4/f/48Dhw4QKXyDCM3K1asiOjoaIuVn8zpurdsiC7x8/Oz+Lqv/G1bt26NEydO0OvOzs60bACorkcAmn0AYOHChdl6HcxgP8EAuSPL8Syt1ylTppiMJRBC4ODBg9TQ3pDKlStjxowZFotBWL16NUaOHEmxD4b4+flpMiiOHTuGkydPAsh8/RYrVow8dN999x0tXejN+vXrMXToULpGAwMDKc0yOTkZv/zyC8nWrl07LF68GAA0VrKlSUhIwLx58zR9gCUybUkWU9HTO2CI9Ort2rWLPJSG3gtjKlSoQEuBzZo10yt19dnuhnTnzh2UL18eAJCenk7raqtXr8b9+/eRkZFB+0rXYGRkJCpXrmzRajmHDh3C1atXAagDUa4BGwZWyXViw8FgLdq2bUuTFUDbbaZYsWLkCk9NTdW8V7JkSXLnh4eHW7T+blRUVKa6zvbQZtCQK1eu0Nru119/nSkf0HCyVbRoUbq5hIaGwt3dPS+nLJAKWN4MW7ZsSbEUmoONuiHVq1ePro1PP/0Unp6eOoqambi4OLRs2RIAkJSURHWL09PTTcoKaBVw8eLFMXny5FytceeHpUuXmq3nLoRA27ZtAaiBZtZUvEwmuBsSwzAMw9gjdm0Bp6enU4TcokWLMr0vg7FGjRpFVqjs4fhfJiwsTNN71djCMERGZAPqjLl69epWkfFZY+HChZksHONlDx2iXQukBSxJS0ujTj2GVZmMr89XXnlF18IYuUVWgTPlljZlAffo0QNlypSxjnBQI51loaFx48aRt8jNzQ2+vr4UcCVTCBmb8Wy7oIGnkYZNmzal9BBALYf2wgsvADCdBsQwzyAFWgEzzH8MdkEzDMMwjD1i9xYww/yHYAuYYQoObAEzDMMwjD3CCphhGIZhbAArYIZhGIaxAayAGYZhGMYGsAJmGIZhGBvACphhGIZhbAArYIZhGIaxAXbfD9jeGTt2LDV8VhQFQ4cOBQCMHDkSpUqVoj6hDx480Bzn5uZGTREY5r/GTz/9RM0tjh8/jnPnztF7ly9fpi5czs7OGDRoEPdXZgokdlmIY8eOHZq/xqSkpCA1NVXTKswY2RD6008/xSeffJJXOc2yadMmAEDnzp2pe4phfdhKlSqhXr16+PPPPwEAsbGxmuMnT56MLl26AEBeO+fkmUOHDgEA1q5di1mzZpncp3z58pg8eTI1A6D0rQAAFFFJREFU9C5evLjV5LNXxowZg7FjxwJ4WhNYZwp0IY6ff/4ZgwcPBgCNws0OLy8vGivDhg3Lg3iMPSNrbicnJ2PixImIjIwEALi6uuKPP/4AAIu1RbUwXIiDYRiGYewRu7OAb926hdq1awMALl68mLMPy6LbT4cOHbBq1arcS5gNtWrVAqA2ZTfskPLWW28BAB4/foyTJ0+a7J4CqA0kpJU+dOhQdO/eXXcZTfH7779T154rV65ku7/stPL5559brCn6yZMn0bhxY3To0AGA6l1ISEgAoPYGli5+W2P4G/r5+WHPnj20PWbMGPqu8tHLuEBawLIxe8OGDcnyff7556m7lI+PD3Xwkdy9excAsH37dhw/fhznz58HoLqu7Y379+8jOTmZtl1dXTXbhjg6OsLDw0PX80sv1siRIxEcHIz58+cDgF5N5S3Kxo0bERoaCkC1gA3v5UIIsoDffPNNm8mYD569bkizZ8/GoEGDAKgXa7NmzQAAmzdvhre3NwC1rdnZs2effpiRAu7atSuKFFGXtz/77DNS6HpiqIDlhb506VK8//77AIATJ07g888/pwvI19eXmoy3a9cOrq6uWL9+PQAgMTER48eP111GQ/bv3w8A+OCDD+jmBgAODg7o2bNnpv3Xrl2LpKQk2g4KCsIPP/wAQP+B3atXL3z77bcm31MUBQ4ODnTTqlatGmbOnAkAePXVV3WVIyuioqLo98sJUgkbKukcUCAV8ObNmwEAbdq0QY0aNQAABw4cQKlSpXL04RkZGTSRtZe4iYsXL2LZsmUA1LG+ZcsWeq9ly5a0/eTJE43ML730Ei2JhYeH6yKHVE537twBAGrz2KxZM9SsWROAOmZbtWqV7/PpQWxsLAIDAwEAZ8+e1RgpL730Ej777DMAQNu2beHl5WUzOWXrTMP7ZVaYmCSwC5phGIZh7BG7i4L+7bff6Hm7du3I6nr06BFZtUIIPHnyhPYztoCdnJzMuqQtgZzJBwUF0WsNGjTAnj17cP/+fdrHuEF2v379rCLf2bNnyb1rOJsrXrw4Jk2ahL59+2Y6JiQkBKmpqRg4cCAA4MiRI3j8+DEA/S3gu3fvol69evj9998zvSeEQO3atem9e/fuIS0tTdfz54TcWL+AajHLv/lwSRcIEhMT6Xn58uUBIMfWLwAUKmR7O+HGjRvYv38/wsLCAAAPHz4kD5GxlWtoDRtz+fJllCxZUje5kpOTyfKVxMTEAFDHrLwPFipUCGXKlKF9jO+Z9erVA6C6hC2B/NyvvvoKcXFxlBWiKAoaNmwIQLV4O3bsCFdXV4vIkBVJSUkUDDZ9+nScOHGCluiMM1iMKVGiBICcW8qG2JUCTkxMxNGjR+lmt3TpUrqwn3vuOVuKlgnpNsnKhe/s7AxnZ2driWSWVatW4dq1a5lenz9/Pjp16mTymNdffx3A04hpS7J06VJkZGRgw4YNAIBPPvkEFSpUAKAO3Bo1alCkeeHCheHi4mJxmYwJDw+nCGhT+Pn5oVGjRpptw7//ZfJyY7IH4uLiMHXqVACqO/LgwYMm9/P19TUbw2EqPqV+/fr5lk3GSHz88cf0WsWKFeHp6UnbchIIqG78pKQk1K1bFwBw+/ZtvPDCCwCAunXrIiAgIN8yGSMnKD179qTIZvl9yIl927Zt4evrq/u5c4qcvAwbNgxLly6l152cnGiSKF3ixjg6OqJt27Z4/vnn83x+208tGYZhGOY/iF1ZwEePHkVCQgIGDBgAAORytkfkzDMuLo5mUYMHDzabc/zSSy+hdOnSVpNPsmDBAprFSyZMmABAO3u2JdKlLV05AChSWwbQOTk5WV8wAwxzgAFtdDa7mbPmlVdeoedyrKSnp2c5vuUyQ0ZGBu7cuUPLH4YWniW4f/8+BUeGhYVRNLMQAiVLlsTy5csBAK1bt8b3339Px1mi1oA5EhIS0Lx5cwCqZS4t7K5du+LLL7+k/c6cOUPP09LScO3aNTRt2hSA6lbNj+WWHXv37qWc7z///FPjBVAUBQ0aNAAAm1q/8fHx5LW6fv06Ba916NABLVq0QLVq1Swug11puJ9//hkA6EuR66fZYbgm6eDgoL9gJpBrQZs2bcLhw4cBqOkAxoUtpIv6tddewzvvvAMAmDZtmkbZWJKUlBQ8evRI89q+ffsAqP+DPayvmUJGINozhulRhkqYlbF55Fi5d++eZkJ64sQJKm6zfv16pKSk0HsPHz5ERkYGAKBs2bI09kJCQnSTS6Y8jhs3DitWrKDX5RJYkyZNMGbMGHLh6n3+nJKeno5Zs2bh9OnTANT7i0zhklX4JMZZAjJFErBMipJcQx00aBA2bdqkSSeSyOft2rUDoCpjuea7fft2jYyWRCrf69ev02tyolihQoVs1331wq7SkIKDg7F27dpcf5iPjw89r1mzJnr37k2zaxcXlywrZuWXpKQkChQbPnx4pvdN5QFXrVoV3377rVVmfytXrkRoaKjJC6ps2bKa7S+++IIGbUJCAt3oJDL1asiQIWjcuLHussp0lbZt21L6xKxZsyxyrtxibAGbIo+pR4YUyDQkee2VKVOGJoNRUVGkVNesWYMlS5YgPT2djqlevToAUOCiLFt5+vRpmjTOmTOHconzi/xMc2lOnTt3xpIlS3Q5V344ePAgWY8AULJkSRw4cACAddPyTCHvJ6byeaXClcpW/p00aRLdIxs2bKhZt7YEcXFxAIDGjRtrlK8xjo6OtG4tU2HzAKchMQzDMIw9YlcW8I0bN9CrVy9yZZw4cULzvrRqy5cvT/sAWVfCKlu2LObMmQMA+PDDD/MvuQlkSlRKSgrWrVsHQK0yVbt2bSrEkZSURIn7gBohPXnyZADQbRZvjpkzZ9J6jF5I60VPZLRs/fr1ycXm7OyMMWPGoGPHjgCgexWhnJITC1hiXCUrFxRIC1gSGBhIbuayZcuSm9nBwQF16tSh8dm0aVNa65WuUmkdb9iwgVLqXF1dyfqrWrVqvv6B7CxgJycneHl5kYfO0mvRxsj7yPvvv69xz+vpBcgvcg01Li4O1atXR9u2bQGoFbqyOkb+b4GBgZQJYSnk8ptMfZK8/PLLFBV+9epVXLp0ieqPSw9nHnj2KmEBoA5CxuXc5CBxdnamfQAgOjqacu/kADdEDuKYmBhybdqSU6dOoX79+qS4t2/fblF3dEZGBl1E27dvp9cjIyM1+dS5/UxL8dNPP6Fr164AgH///RcAKLikV69edqGEjdOOAGgUdB7HVYFWwFOnTtU0U5AF9hctWkRBRdnx4MEDiqU4efIkunXrBgD5dg/LybHhRD4sLIyUncz1lel5v/zyiyav1tLIZZjo6GjN64ZGRbdu3eDh4UEVA22FVMBZIVOU6tatS8aUoih5vh/lFLkc8s0338DT05OupTJlylBcTq9evbBo0SK0bt0aAMgVnQfYBc0wDMMw9ohdWsD5Ze7cudi6dSsANdjj4cOH9N7u3bsBwOaBPeXKlaMi9W+88QaOHTtmdRk2b95s1pK9cOEChgwZonlNLgEMHDgwU2qT3pw8eRIAMH78eEoLAVT3pLk2lbZGFpAxjIjmWtBPOXv2LFma7u7u1NzDME0pJ/zzzz8AgMqVK1OQlqWro/n6+pK7W9KjRw8AqgVvafr37w8AmDdvnuZ14+U3Z2dnVKxYEYBagMde+yjLNq116tQhb5G7uzvdE23J7NmzMXDgQIou37VrV14/KvvxLISwxcNqfP/996JYsWKiWLFiQlEU0alTJ9GpUyeRmppqTTE07Nq1Szg6OgpFUYSiKMLb29tmshjz119/ib/++ktUrFiR5JOPadOmiWnTpllVnn///VcsWLCAZKhevbpVz58bwsPDRXh4uICqkAQAER4enpuPsNV4fGbGsxBCpKSkiJSUFAFAODg4CAcHBxEfH2/Rc16/fl0EBASI559/Xjz//POiSJEi9Bg1apRIS0uz6PklqampYt68eSI0NFSEhoaKv/76i8ZlzZo1hYuLC40VAGLcuHFi3LhxVpEtN3zxxRfiiy++EIUKFSJ5e/XqZWuxhBBCzJkzRwAQLVq0EC1atMjPR2U7duwqD9gSdO/enRLSZ86ciR9//BGAGrQxevRoq8oiS9mFhIRQYQFbI4TAjRs3AKgpATt37gSg1qwFnq6fDx48mMrHWZNSpUpZLTeQsR6rVq2i9b7OnTvn+XNketKOHTtM1jTXCw8PD2zbto3W+WUxGwCYOHEimjRpkimwxxI4OTllCrqSVu6QIUOwa9cufPTRRwDUoieyNeH7779vV+NIBlsJIajMsCwSoierVq2idfzevXubDbLLyMigetVTpkyBo6OjVbpH8RowwzAMw9gAu7aAU1NTdWnCIC1d2UcWAG7dupXvz80N27Ztw6hRowCAumzYmnPnzmHjxo1ZpgnI6OMRI0ZYSyybI9fU9uzZw1WtLMS+ffso1Sw/FrBERlTnl4cPH5JHyFSqkSyTu2TJEpMNTmxNkyZNqJHJnTt3qBPV1q1bdbOA9+7dC0CNDp4xY0auj58wYQL1c1cUhXr+yrQlPZk8eTLFkyxYsIAKghj37v322281sSWhoaFmmzDoiV0r4OnTp9MgCAwMRPHixfP0OaZqzuY3lUVeeFWrVqVgElPIDhumuqWI/w8+sGbHpHPnzmHhwoUA1AEkS/AZ4+vri9mzZ9u8uo4tkErX39+fmqYblp00h3GKCGOeokWL0o1x3759uUrDM1y+kUsksp1efpk4cSK2bdsGwHSqkazUZNwC0N7R0737yy+/AFCr1Mm0xh07dlDwV1YEBgYiMjLS4tWv5LiV1xgAxMbGapYOjJHBgHPnzkWTJk10l8kU7IJmGIZhGBtg1xZwmzZtKKl82rRplBYjK5TklHPnztFz6Z759NNP8yWbdFcsXbqUFvm7dOlCKRL37t3DwoULKUXBVKUuWXnFVA1pvZEz1aCgILNNLkqWLEn1n7t3756pVrStsHR1HGNk6pC/vz8F3URHR2eZUuTv72/xOrYFidDQUPIOde3aFWvWrCEXaVYNQjIyMjQpcNJq0auJ+/79+ykl0NfXl8ZDt27dzFbbq1y5st2MlSNHjmgamch7puwqpgdyySoyMpICXCdPnowFCxaY3D8pKQlfffUVHaMoCgWs5cWFnRO+++47ei6bfoSFhVFwqYuLC9zd3VGuXDkA6viVnkir9nDPSai0BR454ubNm8LJyUk4OTkJRVFEoUKFRKFChYSXl5dYtWqVuHfvnrh3716m4+7fvy/i4+NFfHy86NKliyhRooQoUaKEUBRFjB8/XowfPz6nIpjl2rVr4tq1a6JWrVrC0dFRODo6imbNmgk3Nzfh5uZGssoQe7ktHy+//LK4cOGCuHDhQr5lEUKIxMREceDAAXpERkaKyMhI4enpKTw9PYWLi4smRcEwradBgwaiQYMGYufOnbrIoifnzp0TL774Isnr4+NjtXPv2bNH+Pn5CT8/P01akanUIhikHgGg43KJrdOJrJqGFBUVJaKiosRrr72m+c6WLVsmUlNTNQ+ZetShQwf6jh0cHMSOHTvEjh078ipCJvz9/TUpRvKhKIpmu3jx4qJSpUqiUqVKIi4uTrfz54e4uDjN2A4NDbXo+RYtWkS/haIoIjo6WkRHR9P7iYmJIjExUVSvXp1kcnZ2FrVr1xZnzpwRZ86csZhsQ4YMEUOGDBGNGjUSW7ZsEVu2bBGPHj2y2PnMkO3YYRc0wzAMw9iCnGhpCzxyzM2bN8XNmzdF3bp1M1lv8hESEqJ5ODg4aN6Xs1Z/f3+RkJAgEhIS8jCZMc3WrVtFzZo1Rc2aNTNZucYWcIUKFUSFChVEly5dxN9//62bDEIIsWLFCrPfj7lHrVq1xPnz53WVQ29++eUXoSiKqFatmqhWrZru31tOMbSCc/LII7a2ZK1qAUtSUlLEhx9+SGMmu+9WepyWLFmS31NnYtasWVlawI0bNxaNGzcWy5Yt0/3ceeXy5cvi8uXLwsvLS3PvmTdvnkXPm5SUJLy8vOi8nTt3Fp07dxaLFi0S0dHRtG3oAZw4caJFZbIzsh07z0wpyps3b1LaQmRkJObOnfv0w4T5bkgNGzakfo6WSqWR5dNGjBih6XgEgNKotmzZQuvZLi4uustQr149HDp0KNv9zp49C3d3dwBqFxo90rwswalTpwAALVq0wJUrV6ggujWS482RXUck7gecP+RvHhMTQ2uDp06dwksvvUTpNEFBQZQKJPtT60l6ejoSEhLMvi/HbqlSpXQ/d0548OABpk+fTh2hTp48SamCMrVHNgnZunUrnJycLCqP7GRUt25dSF2iKIrmnvzcc88hMDAQALB8+XKLymNnPJvdkLLj8ePHmkHyzTff0OL6pk2b0KdPH0oN8vPzo1SFgszKlSvxySefmHxv2rRpFPDVpk0biw/K/HL27Fmqw5qQkABFUbB582YAyDLlyxrIQCvDgKuxY8dCp3H0n1bATPYkJiZS4BCgNT6KFi2K9u3bk3FSsmRJi8uTmpoKQO2ANHHiRACqgeTr60v5vQMGDMi2O1IBhbshMQzDMIw98kxawEzBJDY2FoDaAWnNmjX0+vDhwzFp0iRbiWVN2AJmsiQ9PR1z5syhdMdTp06RO/rtt9/GG2+8YUvxGC0F0wXNMAUUVsAMU3BgFzTDMAzD2COsgBmGYRjGBtiqFOWz6mpjGCYzPJ4ZJg+wBcwwDMMwNoAVMMMwDMPYAFbADMMwDGMDWAEzDMMwjA1gBcwwDMMwNoAVMMMwDMPYAFbADMMwDGMDWAEzDMMwjA1gBcwwDMMwNoAVMMMwDMPYAFbADMMwDGMDWAEzDMMwjA1gBcwwDMMwNoAVMMMwDMPYAFbADMMwDGMDWAEzDMMwjA1gBcwwDMMwNoAVMMMwDMPYAFbADMMwDGMDWAEzDMMwjA1gBcwwDMMwNuD/AKcEBE0HrxLgAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 576x576 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_digits(instances, images_per_row=10, **options):\n",
    "    size = 28\n",
    "    images_per_row = min(len(instances), images_per_row)\n",
    "    images = [instance.reshape(size,size) for instance in instances]\n",
    "    n_rows = (len(instances) - 1) // images_per_row + 1\n",
    "    row_images = []\n",
    "    n_empty = n_rows * images_per_row - len(instances)\n",
    "    images.append(np.zeros((size, size * n_empty)))\n",
    "    for row in range(n_rows):\n",
    "        rimages = images[row * images_per_row : (row + 1) * images_per_row]\n",
    "        row_images.append(np.concatenate(rimages, axis=1))\n",
    "    image = np.concatenate(row_images, axis=0)\n",
    "    plt.imshow(image, cmap = matplotlib.cm.binary, **options)\n",
    "    plt.axis(\"off\")\n",
    "\n",
    "\n",
    "# 查看数字3和数字5的例子\n",
    "cl_a, cl_b = 3, 5\n",
    "X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]\n",
    "X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]\n",
    "X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]\n",
    "X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]\n",
    "\n",
    "plt.figure(figsize=(8,8))\n",
    "plt.subplot(221); \n",
    "plot_digits(X_aa[:25], images_per_row=5)\n",
    "plt.subplot(222); \n",
    "plot_digits(X_ab[:25], images_per_row=5)\n",
    "plt.subplot(223);\n",
    "plot_digits(X_ba[:25], images_per_row=5)\n",
    "plt.subplot(224); \n",
    "plot_digits(X_bb[:25], images_per_row=5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 左侧两个是被分类为3的图片\n",
    "# 右侧两个是被分类为5的图片\n",
    "# 大多数错误分类的图片看起来还是非常明显的错误\n",
    "# 原因：SGD是一个线性模型，它所做就是为每个像素分配一个各个类别的权重，当它看到新的图像，将加权后的像素强度汇总，从而得到一个分数进行分类\n",
    "# 数字3和5在一部分像素位上有区别，所以分类器很容易将其弄混\n",
    "# 通过上面图像，如果书写3 的连接点左移，分类器可能将其分类为数字5，这个分类器对图像位移和旋转敏感\n",
    "# 减少混淆的方法之一，就是对图像进行预处理，确保位于中心位置并且没有旋转"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多标签分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 为每个实例产生多个类别 ，例如 照片识别多个人脸\n",
    "# 分类器经过训练可以识别小红，小白，小军，一张照片 里有 小红，小白\n",
    "# 经过分类器，应该输出[1,1,0]， 是小红，是小白，不是小军\n",
    "# 输出多个二元标签的分类系统称为多标签分类系统"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "y_train_large = (y_train >= 7)\n",
    "y_train_odd = (y_train % 2 == 1)\n",
    "y_multilabel = np.c_[y_train_large, y_train_odd]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train, y_multilabel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True]])"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# knn支持多标签分类，不是所有的分类器都支持\n",
    "knn_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 评估多标签分类器方法很多，方法之一就是测量每个标签的F1分数，或者其他二元分类器指标，然后简单平均\n",
    "# y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)\n",
    "# f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")\n",
    "0.977090"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 上面假设了所有标签都同等重要，也可以给每个标签设置一个权重（该目标标签实例的数量），设置average='weighted'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多输出分类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 例子：构建一个系统去除图片中的噪声，输入一张有噪声的图片，它将输入一张干净的数字图片，分类器输出是多个标签，一个像素一个标签，每个标签多个值0到255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加噪声，目标将图片还原为原始图片 创建训练集和测试集\n",
    "noise = np.random.randint(0, 100, (len(X_train), 784))\n",
    "X_train_mod = X_train + noise\n",
    "noise = np.random.randint(0, 100, (len(X_test), 784))\n",
    "X_test_mod = X_test + noise\n",
    "y_train_mod = X_train\n",
    "y_test_mod = X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "some_index = 5500\n",
    "plt.subplot(121);plt.imshow(X_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.subplot(122);plt.imshow(y_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf.fit(X_train_mod, y_train_mod)\n",
    "clean_digit = knn_clf.predict([X_test_mod[some_index]])\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPwAAAD6CAYAAACF8ip6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAADINJREFUeJzt3WGoXPWZx/Hfb5Mr2Nyu3OjsNQZNDMQXxRiI0za3sZCFGDD0RVMqFtIlYsuFLPhCIXSLZcFifbFCUQpNCKQ1CKvYxSxdNmJUGoytsZ2bbqt5UbosSdtshCnG3KgvNhuefZFDc/cm98zcmXNmJj7fD1w8M8858384zo//ueecm+OIEIAc/mrYDQAYHAIPJELggUQIPJAIgQcSIfBAIgQeSITAA4kQeCCRpXUPcNNNN8Xq1avrHgZIbWZm5s8R0ei0Xu2BX716tVqtVt3DAKnZPtXNej0f0tveb/st29/p9TMADFZPgbf9FUlLImJK0hrba6ttC0Adep3hN0t6sVg+LOmeuUXb07ZbtlvtdruP9gBUqdfAL5N0ulh+X9Lk3GJE7IuIZkQ0G42O5xEADEivgf9Q0vXF8ngfnwNggHoN6owuH8avl3Sykm4A1KrXy3L/Kumo7Vsk3SdpY3UtAahLTzN8RMzq0om7Y5L+NiLOVdkUgHr0fONNRJzV5TP1AK4BnGwDEiHwQCIEHkiEwAOJEHggEQIPJELggUQIPJAIgQcSIfBAIgQeSITAA4kQeCARAg8kQuCBRAg8kAiBBxIh8EAiBB5IhMADiRB4IBECDyRC4IFECDyQCIEHEiHwQCIEHkiEwAOJEHggkUUH3vZS23+wfaT4WVdHYwCq18vjou+S9HxEfKvqZgDUq5dD+o2SvmT7l7b32+75GfMABquXwP9K0paI+JykMUnb5q9ge9p2y3ar3W732yOAivQS+N9GxJliuSVp7fwVImJfRDQjotloNPpqEEB1egn8c7bX214i6cuSflNxTwBq0svv39+V9M+SLOmnEfFatS0BqMuiAx8R7+rSmXoA1xhuvAESIfBAIgQeSITAA4kQeCARAg8kwn3wQEUuXLhQWh8bGxtQJwtjhgcSIfBAIgQeSITAA4kQeCARAg8kQuCBRLgOn9CpU6dK6ydOnCit33bbbaX1VatWLVj76KOPSrddsWJFaf2pp54qrc/MzCxYe+GFF0q33b59e2n9448/Lq3v3LmztP7oo48uWDtz5syCtSoxwwOJEHggEQIPJELggUQIPJAIgQcSIfBAIo6IWgdoNpvRarVqHSMj28NuIZ26s9IP2zMR0ey0HjM8kAiBBxIh8EAiBB5IhMADiRB4IBECDyTC38OPqL179w67hQXt3r27tL5u3braxt60aVNpfc2aNbWN/UnQ1Qxve9L20WJ5zPa/2f657YfqbQ9AlToG3vaEpAOSlhVvPSxpJiI2Sfqq7U/X2B+ACnUzw1+U9ICk2eL1ZkkvFstvSOp4Ox+A0dAx8BExGxHn5ry1TNLpYvl9SZPzt7E9bbtlu9Vut6vpFEDfejlL/6Gk64vl8at9RkTsi4hmRDQbjUY//QGoUC+Bn5F0T7G8XtLJyroBUKteLssdkHTI9hclfUbS29W2BKAuXQc+IjYX/z1l+15dmuX/MSIu1tTbJ1rZv58uSbt27er5szs9p3zpUm6/yKqn//MR8d+6fKYewDWCW2uBRAg8kAiBBxIh8EAiBB5IhOszNXnnnXdK681mf3+C8Oyzzy5Y47IbFsIMDyRC4IFECDyQCIEHEiHwQCIEHkiEwAOJcMG2JseOHav18x988MEFazt37qx1bFy7mOGBRAg8kAiBBxIh8EAiBB5IhMADiRB4IBGuw9dkenp6aGM//fTTpfVt27aV1u+4444q28EIYYYHEiHwQCIEHkiEwAOJEHggEQIPJELggUS4Dl+TiCitf/DBB6X1Q4cOldZ37NixYO2RRx4p3Xbr1q2l9ampqdL6/fffX1ovuwdhfHy8dFvUq6sZ3vak7aPF8krbf7J9pPhp1NsigKp0nOFtT0g6IGlZ8dbnJX0vIvbU2RiA6nUzw1+U9ICk2eL1RknftH3c9pO1dQagch0DHxGzEXFuzlsvS9os6bOSpmzfNX8b29O2W7Zb7Xa7smYB9KeXs/S/iIjzEXFR0q8lrZ2/QkTsi4hmRDQbDX7FB0ZFL4F/xfYK25+StFXSuxX3BKAmvVyWe1zSzyT9j6S9EfG7alsCUBd3ul7cr2azGa1Wq9YxUK0DBw6U1sv+TXxJ2r59+4K1l156qZeW0IHtmYhodlqPO+2ARAg8kAiBBxIh8EAiBB5IhMADifDnsbjC3XffXVq//fbbS+sHDx5csHb8+PHSbTds2FBaR3+Y4YFECDyQCIEHEiHwQCIEHkiEwAOJEHggEa7D4wp33nlnaf3NN98sra9cuXLB2ooVK3rqCdVghgcSIfBAIgQeSITAA4kQeCARAg8kQuCBRLgOj0V7++23S+s333zzgjWuww8XMzyQCIEHEiHwQCIEHkiEwAOJEHggEQIPJMJ1eFzh7NmzpfUnnniitL5r164q20GFOs7wtm+w/bLtw7YP2r7O9n7bb9n+ziCaBFCNbg7pd0j6fkRslfSepK9JWhIRU5LW2F5bZ4MAqtPxkD4ifjjnZUPS1yU9Xbw+LOkeSb+vvjUAVev6pJ3tKUkTkv4o6XTx9vuSJq+y7rTtlu1Wu92upFEA/esq8LaXS/qBpIckfSjp+qI0frXPiIh9EdGMiGaj0aiqVwB96uak3XWSfiLp2xFxStKMLh3GS9J6SSdr6w5Apbq5LPcNSRskPWb7MUk/lvR3tm+RdJ+kjTX2hyFYvnx5X9vPzMxU1Amq1s1Juz2S9sx9z/ZPJd0r6Z8i4lxNvQGoWE833kTEWUkvVtwLgJpxay2QCIEHEiHwQCIEHkiEwAOJ8OexNen0yOVnnnmmtH7y5MnS+q233rrYlv7i9ddf73lbSTp69Ghf22N4mOGBRAg8kAiBBxIh8EAiBB5IhMADiRB4IBGuw9fkxIkTpfUtW7YMqJMr7d69u7R+/vz50vr4+HiV7WCAmOGBRAg8kAiBBxIh8EAiBB5IhMADiRB4IBGuw9ckIkrrFy5cKK3Pzs6W1k+fPr1gbWJionTbfv6WHtc2ZnggEQIPJELggUQIPJAIgQcSIfBAIgQeSKTjdXjbN0h6QdISSR9JekDSf0r6r2KVhyPindo6/IQaGxsrrd9444191YGr6WaG3yHp+xGxVdJ7kv5B0vMRsbn4IezANaJj4CPihxHxavGyIel/JX3J9i9t77fN3XrANaLr3+FtT0makPSqpC0R8TlJY5K2XWXdadst2612u11ZswD601XgbS+X9ANJD0n6bUScKUotSWvnrx8R+yKiGRHNRqNRWbMA+tMx8Lavk/QTSd+OiFOSnrO93vYSSV+W9JuaewRQkW5m+G9I2iDpMdtHJJ2Q9Jyk/5D0VkS8Vl97AKrU8YRbROyRtGfe24/X0w6AOnHjDZAIgQcSIfBAIgQeSITAA4kQeCARAg8kQuCBRAg8kAiBBxIh8EAiBB5IhMADiRB4IBECDyTiTo817nsAuy3p1Jy3bpL051oH7R299YbeFq/qvlZFRMd/T672wF8xoN2KiOZAB+0SvfWG3hZvWH1xSA8kQuCBRIYR+H1DGLNb9NYbelu8ofQ18N/hAQwPh/RAIgReku2ltv9g+0jxs27YPY0625O2jxbLK23/ac7+43FD89i+wfbLtg/bPmj7umF85wZ6SG97v6TPSPr3iHhiYAN3YHuDpAci4lvD7mUu25OS/iUivmh7TNJLkpZL2h8RPxpiXxOSnpf0NxGxwfZXJE0WzzAYmgUebb5HI/Cds/33kn4fEa/a3iPpjKRlg/7ODWyGL74USyJiStIa21c8k26INmrEnohbhOqApGXFWw9LmomITZK+avvTQ2tOuqhLYZotXm+U9E3bx20/Oby2rni0+dc0It+5UXkK8yAP6TdLerFYPizpngGO3cmv1OGJuEMwP1SbdXn/vSFpaDeTRMRsRJyb89bLutTfZyVN2b5rSH3ND9XXNWLfucU8hbkOgwz8Mkmni+X3JU0OcOxOOj4Rd9CuEqpR3n+/iIjzEXFR0q815P03J1R/1Ajts8U+hbkOgwz8h5KuL5bHBzx2J9fCE3FHef+9YnuF7U9J2irp3WE1Mi9UI7PPRuUpzIPcATO6fEi1XtLJAY7dyXc1+k/EHeX997ikn0k6JmlvRPxuGE1cJVSjtM9G4inMAztLb/uvJR2V9Lqk+yRtnHfIiquwfSQiNtteJemQpNckfUGX9t/F4XY3WmzvkvSkLs+WP5b0qPjO/cWgL8tNSLpX0hsR8d7ABv6EsH2LLs1Yr2T/4naL79z/x621QCKjdOIHQM0IPJAIgQcSIfBAIgQeSOT/ABQFNPOqFgGTAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(clean_digit.reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "######################"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000,)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "shuffle_index=np.random.permutation(60000) \n",
    "X_train,y_train=X_train[shuffle_index],y_train[shuffle_index]\n",
    "shuffle_index=np.random.permutation(10000) \n",
    "X_test,y_test=X_test[shuffle_index],y_test[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib\n",
    "some_digit=X_train[20000]\n",
    "some_digit_img=some_digit.reshape(28,28)\n",
    "\n",
    "plt.imshow(some_digit_img,cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.0"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[20000]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "                     weights='uniform')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择并且训练模型\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "knn_model = KNeighborsClassifier()\n",
    "knn_model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10000, 784)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "some_digit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([6.])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_pred_some_digit = knn_model.predict(some_digit.reshape(1,-1))\n",
    "y_pred_some_digit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = knn_model.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10000,)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_pred.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ps= [0.96340257 0.95450716 0.98216056 0.96442688 0.9762151  0.96528555\n",
      " 0.98130841 0.96108949 0.98809524 0.95626243] 0.9692753386570571\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score,confusion_matrix \n",
    "\n",
    "ps = precision_score(y_test, y_pred, average=None)\n",
    "print('\\nps=', ps, np.average(ps))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
